Skip to main content
Public BetaMetronome’s NetSuite integration is currently in a Public Beta. Breaking changes may occur between now and GA.
Metronome’s NetSuite integration enables clients to sync invoices and payments to NetSuite for two core use cases:
  • Billing: Send invoices to NetSuite for distribution and collection.
  • Revenue recognition: If a different system (e.g. Stripe) is used for billing, sync invoices and payment status to NetSuite to power revenue operations.

Connect Metronome to NetSuite

To connect Metronome to NetSuite, navigate to the Metronome UI and go to the Connections -> Integrations tab. Select NetSuite from the options in Available Integrations. A pop-up will open that will provide instructions on how to connect Metronome with NetSuite. You will need to:
  • Provide Metronome with your NetSuite account ID
  • Download a permissions bundle (provided in the pop-up screen) to your NetSuite account, which will ensure Metronome has the appropriate permissions to create and read from the necessary objects in NetSuite
  • Provide Metronome with the generated credentials to access your NetSuite account
Once complete, you should see NetSuite listed under the Active Integrations table.
INITIAL OBJECT SYNCAfter creating the connection, it can take Metronome up to an hour to index objects inside of NetSuite. This may cause a delay in syncing invoices after initial set-up.

Map your Metronome products to NetSuite items

Metronome needs to map Metronome products to NetSuite items to ensure invoices sync successfully and revenue is allocated to the appropriate bucket:
  • Create a custom field on the product object. Name it something like netsuite_item_internal_id.
  • For each product in Metronome, set the field with the corresponding internal item ID in NetSuite.
  • Use the entity mapping feature to set the relationship between the Metronome product custom field and the NetSuite item ID. Click on the NetSuite row in the Active Integrations table and select Entity Mapping.

Configure your Metronome customer

Create either billing or revenue system configurations on the Metronome customer object. Once created, these can then be referenced on the customer’s contract to route contract invoices to NetSuite:
  • Customer billing configuration: For billing use cases, Metronome syncs the invoice to NetSuite once the invoice is finalized. NetSuite then handles invoice distribution, tax calculation, and payment collection.
  • Revenue system configuration: Metronome syncs invoices to NetSuite after payment has been attempted in a different system (e.g. Stripe). If payment was successful, Metronome will sync the associated payment information to NetSuite as a payment object. If payment fails upon first attempt but later succeeds, Metronome will create the payment object once successful.

Set the customer billing configuration

If a customer should be billed out of NetSuite, set the customer_billing_configuration as netsuite. This can either be done in the customer create call or after customer creation using the /setCustomerBillingProviderConfigurations end point or the UI. See example below:
curl https://api.metronome.com/v1/setCustomerBillingProviderConfigurations \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "data": [
      {
        "customer_id": "4db51251-61de-4bfe-b9ce-495e244f3491",
        "billing_provider": "netsuite",
        "configuration": {
          "netsuite_customer_id": "58877111"
        },
        "delivery_method_id": "5b95d955-b705-41c8-9d2e-34ccbdee5193"
      }
    ]
  }'
SET CONFIGURATION ON CONTRACTMetronome allows you to set multiple customer_billing_configuration per customer. Given this, once a customer_billing_configuration has been set, you must set the config on the relevant contract in order for Metronome to send the contract invoices to NetSuite.

Set the revenue system configuration

If the customer is billed outside of NetSuite, but NetSuite needs the invoice information for revenue recognition, set up a revenue_system_configuration for the customer via the API or UI. Metronome syncs both invoices and payments (if available) for contracts with a revenue system configuration. If payment fails for the invoice after the first attempt, Metronome will still sync the invoice to NetSuite as OPEN. If payment is reattempted later and succeeds, Metronome will retroactively update the associated invoice in NetSuite as ‘PAID’. See an example below for setting the revenue_system_configuration via the setCustomerRevenueSystemConfigurations end point:
curl https://api.metronome.com/v1/setCustomerRevenueSystemConfigurations \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
    "data": [
		{
			"customer_id": "7b8864ad-5238-4ec2-8b89-bee635e1876b",
      		"provider": "netsuite",
 			"configuration": {
 				"netsuite_customer_id": "58771"
 			},
 			"delivery_method_id": "6fe89b5a-41d0-413b-bb44-5f90522db8a2"
 		}
	]
}'
SET CONFIGURATION ON CONTRACTMetronome allows you to set multiple revenue_system_configuration per customer. Given this, once a revenue_system_configuration has been set, you must set the config on the relevant contract in order for Metronome to send the contract invoices and associated payments to NetSuite.

Provision the customer’s contract

Either the customer_billing_configuration or the revenue_system_configuration need to be set on a contract in order for Metronome to sync invoices to NetSuite. This provides you with flexibility to route invoices to different places on a per contract basis. Let’s look at an example of a company:
  • All PLG customers are billed out of Stripe. These are self-serve customers that are charged a $10 monthly subscription fee in return for 5 AI credits.
  • All SLG customers are billed out of NetSuite. These customers pay in quarterly installments for annual usage commitments.
For PLG customers, I want Metronome to collect payment in Stripe and then sync the invoice to NetSuite. To enable this, there are two API calls I need to make to Metronome when a new PLG customer signs up: create a customer and create a contract. See example below for creating the customer object. This API call includes the creation of the customer_billing_configuration, and revenue_system_configuration:
curl https://api.metronome.com/v1/customers \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
		  "ingest_aliases": [
		    "plgcustomer1@example.com"
		  ],
		  "name": "Customer 01",
		  "customer_billing_provider_configurations": [
			{
				"billing_provider": "stripe",
				"delivery_method": "direct_to_billing_provider",,
				"configuration": {
					"stripe_customer_id": "cus_123",
        			"stripe_collection_method": "charge_automatically"
		    	}
			}
		  ],
		  "revenue_system_configuration": [
			{
	      		"provider": "netsuite",
	 			"configuration": {
	 				"netsuite_customer_id": "58771"
	 			},
	 			"delivery_method_id": "6fe89b5a-41d0-413b-bb44-5f90522db8a2"
			}
		  ]
	  }'
Next, see example below for creating the PLG contract for the customer with the customer_billing_configuration and revenue_system_configuration set on it. In order to get the revenue_system_configuration_id and billing_provider_configuration_id, you will need to call the fetch billing provider and revenue system configuration end-points:
curl https://api.metronome.com/v1/customers \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
	  	"customer_id": "4c09936b-455d-4c72-a120-d71b600a7546",
		"rate_card_id": "740a2ca1-64f6-417d-807a-05f154b3b1fe",
		"starting_at": "2025-06-01T00:00:00.000Z",
		"billing_provider_configuration": {
		    "billing_provider_configuration_id": "e045c62b-65e7-4e84-a924-3f06f8b621d0" // UUID of previously created customer billing configuration
		},
		"revenue_system_configuration": {
			"revenue_system_configuration_id": "d455j33b-12f7-4b76-a924-3f06f8b687q9" // UUID of previously created revenue system configuration
		},
		"overrides": [
		    {
		        "starting_at": "2025-04-01T00:00:00.000Z",
		        "override_specifiers": [
		            {
		                "billing_frequency": "annual",
		                "product_id": "ed518bcb-acc1-4cd8-85dd-880c2eb38994"
		            }
	            ],
	            "entitled": true
		    }
		],
	    "subscriptions": [
	        {
	            "collection_schedule": "advance",
		        "initial_quantity": 1,
	            "proration": {
	                "invoice_behavior": "bill_on_next_collection_date",
		            "is_prorated": true
		        },
	            "subscription_rate": {
	                "billing_frequency": "monthly",
		            "product_id": "ed518bcb-acc1-4cd8-85dd-880c2eb38994"
		        },
	            "description": "Basic tier",
	            "name": "Basic Plan",
		        "custom_fields": {
			         "plan_tier": "basic"
		        },
	            "temporary_id": "basic_plan_monthly"
	        }
		],
	    "recurring_credits": [  
	      {  
		    "access_amount": {  
		    	"credit_type_id": "d3cb2827-dcb5-44af-9354-947a7197b9a6",  
		        "unit_price": 5  
		    },  
		    "commit_duration": {  
	        	"value": 1,  
		        "unit": "periods"  
		    },  
		    "priority": 1,   
	        "product_id": "652e1298-7638-45a8-b691-cdf47e46cbc8",  
	        "starting_at": "2025-06-01T00:00:00Z",  
		    "subscription_config": {  
		    	"subscription_id": "basic_plan_monthly",  
		        "apply_seat_increase_config": {  
		        	"is_prorated": true  
		        }  
		    }  
		  }  
		]
	  }'

Tax

To calculate tax for invoices in NetSuite, you need to integrate NetSuite with your preferred tax provider. Metronome does not calculate nor sync tax amounts to NetSuite. The tax flow will look as follows:
  • Metronome creates an invoice in NetSuite.
  • Tax integration in NetSuite adds tax to invoice.
This set-up is required regardless of whether you are using NetSuite for billing or just for revenue recognition.

Additional configuration

Metronome also syncs additional metadata to the NetSuite invoice object to help with reconciliation workflows. To enable, create the following custom fields on your NetSuite invoice object with the following id (all case sensitive):
  • metronome_invoice_id: Metronome will store the associated Metronome invoice_id on this field.
  • metronome_contract_id: Metronome will store the associated Metronome contract_id on this field.
  • metronome_customer_id: Metronome will store the associated Metronome customer_id on this field.
If these custom fields are not set-up, Metronome will be unable to sync the associated metadata.

Manage the integration

When Metronome sends invoices to NetSuite, it records information across four surface areas to help you manage state of each object and ensure all data is synced correctly: the UI, API, data export, and webhook notifications. Leverage this information to adjudicate potential sync issues and ensure all data successfully sends to NetSuite.

Invoice state

Metronome will record information in distinct places on the invoice object depending on whether NetSuite is configured as the customer_billing_configuration or the revenue_system_configuration.

Successful syncs

When NetSuite is set as the customer_billing_configuration, sync details will be stored in the external_invoice object. The invoice status will be reflected in the external_status property and the created NetSuite invoice id is stored oin the external_invoice.invoice_id property. See a /getInvoice example below:
curl https://api.metronome.com/v1/customers \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
	    "id": "8f653259-640d-5a10-9636-2c7682a355fe",
	    "start_timestamp": "2026-02-11T00:00:00+00:00",
        "end_timestamp": "2026-02-11T00:00:00+00:00",
	    "issued_at": "2026-02-11T00:00:00+00:00",
	    "customer_id": "43536714-7f62-4e27-abcd-492d231ab7a0",
		// ...
		"external_invoice": {
			"billing_provider_type": "netsuite",
	        "invoice_id": "61112", // NetSuite invoice id
	        "issued_at_timestamp": "2026-02-11T00:00:00+00:00",
	        "external_status": "FINALIZED"
			// ...
	}'
Upon initial success, Metronome will emit a invoice.invoice_sync_status webhook notification providing the invoice details:
{
  "id": "65472d2c-c51f-46b2-95b3-0eaeb5c3dc5a",
  "invoice_id": "a43c2489-3d2f-40a2-a469-16411c535406",
  "customer_id": "faeff926-0a94-45da-9048-5b9d381b608b",
  "contract_id": "dfaa1fd8-d4d7-42c0-b2ab-9cc532793ca7",
  "sync_type": "billing_provider,
  "external_invoice": {
  	"billing_provider_type": "netsuite",
	"invoice_id": "9ae574fb-9d56-51c2-9077-b78971e9fe5b", // NetSuite invoice id
	"issued_at_timestamp": "2026-02-11T00:00:00+00:00",
	"external_status": "FINALIZED",
	// ...
  }
}
If the invoice status changes in NetSuite, Metronome will update the external_status to reflect the new invoice state. Expect approximtely one-hour latency for these status updates. When NetSuite is set as the revenue_system_configuration, sync details will be stored in the revenue_system_invoices object on the invoice API. See example below:
curl https://api.metronome.com/v1/customers \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
	    "id": "8f653259-640d-5a10-9636-2c7682a355fe",
	    "start_timestamp": "2026-02-11T00:00:00+00:00",
        "end_timestamp": "2026-02-11T00:00:00+00:00",
	    "issued_at": "2026-02-11T00:00:00+00:00",
	    "customer_id": "43536714-7f62-4e27-abcd-492d231ab7a0",
		// ...
    	"revenue_system_invoices": [
        	{
	            "revenue_system_provider": "NETSUITE",
	            "revenue_system_external_entity_id": "458886",
	            "sync_status": "SUCCEEDED",
	            "revenue_system_external_entity_type": "NETSUITE_INVOICE"
            }
        ]
	}'
Similarly, Metronome will emit a invoice.invoice_sync_status webhook notification with sync_type set to revenue_system.

Sync failures

When NetSuite is set as the customer_billing_configuration, external_status will be updated to INVALID_REQUEST_ERROR in the event of a failure. The error message will be stored in the billing_provider_error property. See a /getInvoice API example below:
curl https://api.metronome.com/v1/customers \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
	    "id": "8f653259-640d-5a10-9636-2c7682a355fe",
	    "start_timestamp": "2026-02-11T00:00:00+00:00",
        "end_timestamp": "2026-02-11T00:00:00+00:00",
	    "issued_at": "2026-02-11T00:00:00+00:00",
	    "customer_id": "43536714-7f62-4e27-abcd-492d231ab7a0",
		// ...
		"external_invoice": {
	        "billing_provider_type": "netsuite",
            "external_status": "INVALID_REQUEST_ERROR",
			"billing_provider_error": "We've encountered the following error when trying to access the NetSuite API: Failed to create Netsuite Invoice object. No item id found 5551."
		},
		// ...
	}'
When the error occurs, Metronome will emit a invoice.invoice_sync_status webhook notification providing the invoice details with associated error information. Clients should consume these webhooks to identify when an invoice fails to sync to NetSuite and adjudicate based on error details. In the example given above, the error message identifies that the item id for one of the Metronome products is incorrect. To address this problem, update the corresponding custom field with the correct NetSuite item id. Once fixed, you can reattempt the sync to NetSuite via the UI by clicking Send to NetSuite button on the invoice UI page. When NetSuite is set as the revenue_system_configuration, sync_status will be updated to FAILED in the event of a failure. The associated error for why the invoice failed will be stored in the error_message property. See example below:
curl https://api.metronome.com/v1/customers \
  -H "Authorization: Bearer <TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
	    "id": "8f653259-640d-5a10-9636-2c7682a355fe",
	    "start_timestamp": "2026-02-11T00:00:00+00:00",
        "end_timestamp": "2026-02-11T00:00:00+00:00",
	    "issued_at": "2026-02-11T00:00:00+00:00",
	    "customer_id": "43536714-7f62-4e27-abcd-492d231ab7a0",
		// ...
        "revenue_system_invoices": [
            {
	            "revenue_system_provider": "NETSUITE",
	            "sync_status": "FAILED",
                "revenue_system_external_entity_type": "NETSUITE_INVOICE",
	            "error_message": "We've encountered the following error when trying to access the NetSuite API: Failed to create Netsuite Invoice object. No item id found 5551."
            }
        ]
	}'

Payment state

If Stripe is used for billing and NetSuite is configured as the revenue system, Metronome will first create an invoice object in Stripe. If the payment is successful:
  • Metronome will store the payment intent id and payment amount inside the external_invoice object in the external_payment_id and invoiced_total fields respectively.
  • When then syncing the invoice to NetSuite, Metronome will mark the invoice as PAID and create a linked payment object.
Similar to the invoice sync, Metronome will emit a payment.payment_status_sync webhook notification to indicate success or failure of sending the payment object to NetSuite.