Skip to main content
This guide describes how to migrate from contract amendments to contract edits, released in February of 2025.

Introducing contract editing

Contract editing is a new feature in Metronome used to make changes to a contract. You can edit:
  • Commit and credit access and invoice schedules
  • Applicable product IDs and tags on a commit
  • Scheduled charge invoice schedules
Common uses include editing a contract to fix a mistake or to reflect a mid-term contract upsell.

Contract edits replace amendments

Amendments on contracts are only additive; you can add new commits, credits, scheduled charges, and overrides, but you can’t remove or edit existing objects on the contract. Due to these limitations, we’re replacing amendments with contract editing. To use contract editing, you must update your integration to stop using amendments. After migrating to editing, you’ll no longer have access to create amendments in the UI or with the API.

New functionality

Contract edits introduce new endpoints, data export tables, and scheduled invoice logic.

New endpoints to support editing

As part of the contract edits feature, use these improved endpoints:
  • /v2/contracts/edit: Used to edit a contract; add scheduled charges, commits and credits, and overrides or edit commit and credit access and invoice schedules.
  • /v2/contracts/get: This new version of the /contracts/get endpoint returns the current state of a contract, inclusive of amendments and edits. Amendments and edits are not returned in a separate object. Use the as_of_date parameter to view the full contract, inclusive of amendments and edits as of a previous timestamp. Usage filters are now returned as schedule segments.
  • v2/contracts/list: This new version of the /contracts/list endpoint returns the current state of a customer’s contracts, inclusive of amendments and edits. Amendments and edits are not returned on a separate object. Usage filters are now returned as schedule segments.
  • v2/contracts/getEditHistory: A new endpoint that lists the edits on a contract. Includes all amendments and existing events up-versioned to be edits. For example, updating the contract end date, adding usage filters with the setUsageFilter endpoint, or truncating commits using the updateCommitEndDate endpoint.

New data export tables

The contract edits feature introduces new data export tables. The contract_edits table contains the ID of each edit, timestamp when the edit was made, and describes all edits made on the contract. One row represents an edit made to the contract. This table includes all existing amendments and events up-versioned to be edits. For example, a updating contract end date through the API or UI. This table’s schema includes:
  • id
  • contract_id
  • timestamp
  • edits
  • metadata
  • created_by
  • updated_at
The usage_filter_schedule table provides a more ergonomic way to understand a contract’s usage filters, mimicking the result of the the /v2/contracts/get endpoint. Previously, the usage_filters table only included the starting_at value associated with a filter. This meant you had to add additional logic to understand which filters were active at a given time. Now, each row includes a starting_at value and an ending_before value. This table’s schema includes:
  • id
  • contract_id
  • starting_at
  • ending_before
  • group_key
  • group_values
  • metadata
  • updated_at

Updated logic for scheduled invoices

Prior to contract editing, when multiple scheduled charges shared the same timestamp but were created on different contract amendments, the scheduled charges went on separate invoices. For example, a prepaid commit payment and a scheduled charge occurring on the same date but created through different amendments appeared on different invoices. Contract editing now consolidates all scheduled charges with matching timestamps onto a single invoice, even if they were created through edits. This provides customers with a more streamlined billing experience by delivering one comprehensive invoice for all charges due on the same date. To understand this new logic, consider an example where scheduled charges share the same date. On December 10, 2024, two charges were scheduled to be issued:
  • The first scheduled charge was scheduled to be issued during contract creation.
  • The second scheduled charge was scheduled to be issued through a contract amendment.
Under the old logic, Metronome would create two separate invoices issued on December 10, 2024. If instead the second scheduled charge was created using a contract edit (rather than an amendment), the outcome would be different. As the two scheduled charges share the same timestamp, they’re combined into a single invoice issued on December 10, 2024.

How to migrate to edits

Migrating from amendments to edits includes 4 steps: start using v2 contract endpoints, enable new data export tables, update your amend contract API workflows, and let your Metronome representative know when you’re finished.

1. Start using /v2/contracts/get and /v2/contracts/list

The v1 /contracts/get and /contracts/list endpoints aren’t compatible with contract editing. You now have access to two new endpoints that provide more ergonomic response shapes: /v2/contracts/get and /v2/contracts/list. To start using the new endpoints:
  1. Migrate any automated usage of /v1/contracts/get and /v1/contracts/list to the new endpoints.
  2. After confirming that you’re no longer using those v1 endpoints, contact your Metronome representative. They’ll grant you the ability to use contract editing, which includes using the new /v2/contracts/edit endpoint to edit contracts with the API and the ability to edit a contract in the UI.
:::warning Once contract editing is enabled, you’ll lose the ability to add amendments through the UI. However, you can still call /contracts/amend with the API. ::: The /v1/contracts/get response contains separate fields for current, initial, and amendments. current contains the current state of the contract. For example, see this response:
{
    "data": {
        "amendments": [
            {
                "commits": [
                    {
                        "access_schedule": {
                            "credit_type": {
                                "id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2",
                                "name": "USD (cents)"
                            },
                            "schedule_items": [
                                {
                                    "amount": 20000,
                                    "ending_before": "2025-05-01T00:00:00+00:00",
                                    "id": "7fe2e509-b531-4f8e-8c5b-224b560cf35a",
                                    "starting_at": "2025-02-01T00:00:00+00:00"
                                }
                            ]
                        },
                        "applicable_contract_ids": [
                            "51f66575-81cc-49d1-9a3f-55b97423342e"
                        ],
                        "contract": {
                            "id": "51f66575-81cc-49d1-9a3f-55b97423342e"
                        },
                        "custom_fields": {},
                        "id": "c0a6b92a-851d-403c-b705-62e89467355a",
                        "invoice_schedule": {
                            "credit_type": {
                                "id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2",
                                "name": "USD (cents)"
                            },
                            "schedule_items": [
                                {
                                    "amount": 20000,
                                    "id": "7b19a696-026d-4921-9999-27c33fdb10ab",
                                    "invoice_id": "39c80bd1-357a-5268-88e1-bc1e7a06e082",
                                    "quantity": 1,
                                    "timestamp": "2025-02-19T00:00:00+00:00",
                                    "unit_price": 20000
                                }
                            ]
                        },
                        "priority": 100,
                        "product": {
                            "id": "35a467c7-fc24-46c2-884b-66af8d349674",
                            "name": "Support"
                        },
                        "rate_type": "LIST_RATE",
                        "type": "PREPAID"
                    }
                ],
                "created_at": "2025-02-19T19:42:14.117000+00:00",
                "created_by": "Username",
                "credits": [],
                "id": "2e200c08-9b73-438f-a36b-4488e979b7c3",
                "overrides": [],
                "scheduled_charges": [],
                "starting_at": "2025-02-19T00:00:00+00:00"
            }
        ],
        "current": {
            "commits": [
                {
                    "access_schedule": {
                        "credit_type": {
                            "id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2",
                            "name": "USD (cents)"
                        },
                        "schedule_items": [
                            {
                                "amount": 20000,
                                "ending_before": "2025-05-01T00:00:00+00:00",
                                "id": "7fe2e509-b531-4f8e-8c5b-224b560cf35a",
                                "starting_at": "2025-02-01T00:00:00+00:00"
                            }
                        ]
                    },
                    "applicable_contract_ids": [
                        "51f66575-81cc-49d1-9a3f-55b97423342e"
                    ],
                    "contract": {
                        "id": "51f66575-81cc-49d1-9a3f-55b97423342e"
                    },
                    "custom_fields": {},
                    "id": "c0a6b92a-851d-403c-b705-62e89467355a",
                    "invoice_schedule": {
                        "credit_type": {
                            "id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2",
                            "name": "USD (cents)"
                        },
                        "schedule_items": [
                            {
                                "amount": 20000,
                                "id": "7b19a696-026d-4921-9999-27c33fdb10ab",
                                "invoice_id": "39c80bd1-357a-5268-88e1-bc1e7a06e082",
                                "quantity": 1,
                                "timestamp": "2025-02-19T00:00:00+00:00",
                                "unit_price": 20000
                            }
                        ]
                    },
                    "priority": 100,
                    "product": {
                        "id": "35a467c7-fc24-46c2-884b-66af8d349674",
                        "name": "Support"
                    },
                    "rate_type": "LIST_RATE",
                    "type": "PREPAID"
                }
            ],
            "created_at": "2025-02-19T19:41:52.228000+00:00",
            "created_by": "Username",
            "credits": [],
            "multiplier_override_prioritization": "LOWEST_MULTIPLIER",
            "name": "Awu's test rate card",
            "overrides": [],
            "rate_card_id": "c38bc471-0c45-41d1-b802-0bae4554e771",
            "recurring_commits": [],
            "recurring_credits": [],
            "scheduled_charges": [],
            "starting_at": "2025-02-01T00:00:00+00:00",
            "transitions": [],
            "usage_statement_schedule": {
                "billing_anchor_date": "2025-02-01T00:00:00+00:00",
                "frequency": "MONTHLY"
            }
        },
        "custom_fields": {},
        "customer_id": "c29ccca3-4a0a-4bed-8480-03098685eac2",
        "id": "51f66575-81cc-49d1-9a3f-55b97423342e",
        "initial": {
            "commits": [],
            "created_at": "2025-02-19T19:41:52.228000+00:00",
            "created_by": "Username",
            "credits": [],
            "discounts": [],
            "multiplier_override_prioritization": "LOWEST_MULTIPLIER",
            "name": "Test rate card",
            "overrides": [],
            "rate_card_id": "c38bc471-0c45-41d1-b802-0bae4554e771",
            "recurring_commits": [],
            "recurring_credits": [],
            "reseller_royalties": [],
            "scheduled_charges": [],
            "starting_at": "2025-02-01T00:00:00+00:00",
            "transitions": [],
            "usage_statement_schedule": {
                "billing_anchor_date": "2025-02-01T00:00:00+00:00",
                "frequency": "MONTHLY"
            }
        }
    }
}
By default, the /v2/contracts/get endpoint returns the current state of the contract. The response is similar to the data nested under the current field in the v1/contracts/get response. This example shows the /v2/contracts/get response:
{
    "data": {
        "commits": [
            {
                "access_schedule": {
                    "credit_type": {
                        "id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2",
                        "name": "USD (cents)"
                    },
                    "schedule_items": [
                        {
                            "amount": 20000,
                            "ending_before": "2025-05-01T00:00:00+00:00",
                            "id": "7fe2e509-b531-4f8e-8c5b-224b560cf35a",
                            "starting_at": "2025-02-01T00:00:00+00:00"
                        }
                    ]
                },
                "applicable_contract_ids": [
                    "51f66575-81cc-49d1-9a3f-55b97423342e"
                ],
                "contract": {
                    "id": "51f66575-81cc-49d1-9a3f-55b97423342e"
                },
                "custom_fields": {},
                "id": "c0a6b92a-851d-403c-b705-62e89467355a",
                "invoice_schedule": {
                    "credit_type": {
                        "id": "2714e483-4ff1-48e4-9e25-ac732e8f24f2",
                        "name": "USD (cents)"
                    },
                    "schedule_items": [
                        {
                            "amount": 20000,
                            "id": "7b19a696-026d-4921-9999-27c33fdb10ab",
                            "invoice_id": "39c80bd1-357a-5268-88e1-bc1e7a06e082",
                            "quantity": 1,
                            "timestamp": "2025-02-19T00:00:00+00:00",
                            "unit_price": 20000
                        }
                    ]
                },
                "priority": 100,
                "product": {
                    "id": "35a467c7-fc24-46c2-884b-66af8d349674",
                    "name": "Support"
                },
                "rate_type": "LIST_RATE",
                "type": "PREPAID"
            }
        ],
        "created_at": "2025-02-19T19:41:52.228000+00:00",
        "created_by": "Username",
        "credits": [],
        "custom_fields": {},
        "customer_id": "c29ccca3-4a0a-4bed-8480-03098685eac2",
        "id": "51f66575-81cc-49d1-9a3f-55b97423342e",
        "multiplier_override_prioritization": "LOWEST_MULTIPLIER",
        "name": "Test rate card",
        "overrides": [],
        "rate_card_id": "c38bc471-0c45-41d1-b802-0bae4554e771",
        "recurring_commits": [],
        "recurring_credits": [],
        "scheduled_charges": [],
        "starting_at": "2025-02-01T00:00:00+00:00",
        "transitions": [],
        "usage_filter": [],
        "usage_statement_schedule": {
            "billing_anchor_date": "2025-02-01T00:00:00+00:00",
            "frequency": "MONTHLY"
        }
    }
}
With the /v2/contracts/get endpoint you can specify an as_of_date. The response returns the state of the contract as of that timestamp in the past. This example response shows how you can pass the timestamp when the contract was initially created as the as_of_date to view the initial contract, with no edits:
{
    "data": {
        "commits": [],
        "created_at": "2025-02-19T19:41:52.228000+00:00",
        "created_by": "Username",
        "credits": [],
        "custom_fields": {},
        "customer_id": "c29ccca3-4a0a-4bed-8480-03098685eac2",
        "id": "51f66575-81cc-49d1-9a3f-55b97423342e",
        "multiplier_override_prioritization": "LOWEST_MULTIPLIER",
        "name": "Test rate card",
        "overrides": [],
        "rate_card_id": "c38bc471-0c45-41d1-b802-0bae4554e771",
        "recurring_commits": [],
        "recurring_credits": [],
        "scheduled_charges": [],
        "starting_at": "2025-02-01T00:00:00+00:00",
        "transitions": [],
        "usage_filter": [],
        "usage_statement_schedule": {
            "billing_anchor_date": "2025-02-01T00:00:00+00:00",
            "frequency": "MONTHLY"
        }
    }
}

2. Enable new data export tables

If you use the amendments or usage_filters data export tables, let your Metronome representative know and they’ll enable the contract_edits and usage_filter_schedule tables for you. If you use the amendments data export table, update your workflow to point to the contract_edits table. All historical amendments are included as rows in the contract_edits data table. If you use the usage_filters data export table, update your workflow to use the usage_filter_schedule table.

3. Update your /contracts/amend API workflows

Switching to /v2/contracts/edit gives you more flexibility in making changes to a contract. If you only amend contracts through the UI, there’s no action needed. If you have automated workflows built around the /contracts/amend endpoint, update them to use the new /v2/contracts/edit endpoint. The /contracts/amend and /v2/contracts/edit endpoints share similar syntax for adding new objects to a contract. For example, this request amends the contract to add an overwrite override to a product.
{
    "customer_id": "e15ce0e6-33f0-44bb-89c7-05bc296f5b5e",
    "contract_id": "f9e0b117-42e0-4145-b524-b97302a57518",
    "starting_at": "2025-02-01T00:00:00.000Z",
    "overrides": [
        {
            "starting_at": "2025-02-01T00:00:00Z",
            "type": "OVERWRITE",
            "product_id": "fac0de5f-f00c-468c-9490-cc64c5d5a696",
            "overwrite_rate": {
                "rate_type": "tiered",
                "tiers": [
                    {
                        "size": 2000,
                        "price": 0
                    },
                    {
                        "size": 2000,
                        "price": 100
                    },
                    {
                        "price": 200
                    }
                ]
            }
        }
    ]
}
This next example request does the same thing, but using the /v2/contracts/edit endpoint. Note that the contents of add_overrides are identical to the contents of overrides when calling the /contracts/amend endpoint. There’s also no effective date associated with edits. When calling /contracts/amend you had to pass in a starting_at date for the amendment that was unused. Edits occur immediately, and may involve changes to a schedule. For example, this API request immediately adds an override that starts on Feb 1, 2025:
{
    "customer_id": "e15ce0e6-33f0-44bb-89c7-05bc296f5b5e",
    "contract_id": "f9e0b117-42e0-4145-b524-b97302a57518",
    "add_overrides": [
        {
            "starting_at": "2025-02-01T00:00:00Z",
            "type": "OVERWRITE",
            "product_id": "fac0de5f-f00c-468c-9490-cc64c5d5a696",
            "overwrite_rate": {
                "rate_type": "tiered",
                "tiers": [
                    {
                        "size": 2000,
                        "price": 0
                    },
                    {
                        "size": 2000,
                        "price": 100
                    },
                    {
                        "price": 200
                    }
                ]
            }
        }
    ]
}
You can also use /v2/contracts/edit to edit existing objects. For example, this API call edits the access and invoice schedules for a commit:
{
    "customer_id": "b8bf6a8a-40ee-4809-880f-1ce5ec4ce8c3",
    "contract_id": "39342047-5404-4503-b941-d9be42a8c578",
    "update_commits": [
        {
            "commit_id": "a0383796-fe56-4195-b2e2-d656281bdd41",
            "access_schedule": {
                "update_schedule_items": [
                    {
                        "id": "fd4b4bf4-11d2-4de0-913a-c8786d540ac3",
                        "ending_before": "2025-03-05T00:00:00.000Z"
                    }
                ]
            },
            "invoice_schedule": {
                "update_schedule_items": [
                    {
                        "id": "a2ffa942-9bfb-4142-8eec-7c517d0febdc",
                        "timestamp": "2025-03-05T00:00:00.000Z"
                    }
                ]
            }
        }
    ]
}

4. Contact Metronome

When finished with your migration, contact your Metronome representative to confirm you’ve completed the migration. At this point, Metronome removes your access to:
  • The /v1/contracts/get, /v1/contracts/list, and /contracts/amend endpoints
  • Adding an amendment through the UI
  • Updates to the amendments or usage_filters data export tables
Overall, migrating to edits unlocks powerful new capabilities for your workflows. We’ll continue expanding these features to give you even more control over your contracts.