Skip to main content
These routes start with /api/public. Get an API key, read Authorization, and use Ad accounts to find ad_account_id before you start. The examples use sample UUIDs. Replace them with your own IDs. Each curl block has a copy control.

List metrics

GET /api/public/custom-metrics Set the required ad_account_id. You can filter by query, status (active, archived, or all), or entity_level. Use limit (1–100, default 50) and cursor for more pages. Request
Response: HTTP 200
Keep the account and filters the same when you use next_cursor.

Create a metric

POST /api/public/custom-metrics Send a unique Idempotency-Key header and the metric definition. The account UUID comes from Ad accounts. Request
Response: HTTP 201
A replay with the same key and payload returns the same definition. A different payload with that key returns HTTP 409.

Get a metric

GET /api/public/custom-metrics/{metric_id} Set the metric UUID in the path and ad_account_id in the query. Request
Response: HTTP 200

Edit a metric

PATCH /api/public/custom-metrics/{metric_id} Send ad_account_id and the last updated_at from a read. This prevents an edit from overwriting a newer definition. You can change the label, description, input levels, or status. Request
Response: HTTP 200
A stale updated_at returns a conflict. Read the metric again before you retry.

Download the CSV template

GET /api/public/custom-metrics/template.csv Set ad_account_id. This route returns the current CSV format and metric keys for that account. Save the response as a file before you prepare a CSV import. Request
Response: HTTP 200
Open the saved file to see its headers. Keep those headers when you add rows.

Prepare JSON rows

POST /api/public/custom-metric-imports Send an account UUID, an idempotency key, and up to 1,000 daily rows. value is a decimal string. Use a closed date in the account time zone. Request
Response: HTTP 200
Preparation checks the rows and returns a preview. It does not write values. A zero is "0"; a missing row leaves a stored value unchanged.

Prepare a CSV file

POST /api/public/custom-metric-imports/file Send the current CSV template with rows as multipart form data. The account and idempotency key are form fields. Request
Response: HTTP 200
Review the returned preview before you commit the task.

List imports

GET /api/public/custom-metric-imports Set ad_account_id. Use limit (1–100, default 50) and cursor to read more tasks. Request
Response: HTTP 200

Get an import

GET /api/public/custom-metric-imports/{import_id} Use the task_id from a prepare response as import_id. Set ad_account_id. You can send error_cursor to read more validation errors. Request
Response: HTTP 200
Poll this route after you commit until status is completed or failed. A failed task can have some values applied; check counts and progress.

Commit an import

POST /api/public/custom-metric-imports/{import_id}/commit Commit a valid prepared task after you check its preview. Set ad_account_id in the query. Request
Response: HTTP 202
A new accepted task returns HTTP 202. A replay can return HTTP 200. Use Get an import to check the final status.

Create a CSV upload grant

POST /api/public/custom-metric-upload-grants Use this route if your client cannot send a multipart file. Send the file name, exact byte size, content type, account, and idempotency key. Request
Response: HTTP 200
The grant has a short expiry. Keep its authorization value out of logs. Use the returned URL and header for the upload.

Upload CSV bytes

PUT /api/public/custom-metric-uploads/{upload_id} Send raw CSV bytes to the exact upload_url from the grant. Use its authorization value, not the team API key. The uploaded file prepares an import task. Request
Response: HTTP 200
Replace the URL and upload token with the values from Create a CSV upload grant. Commit the returned task after you check its preview.

Query metric values

POST /api/public/metrics/query Send an account UUID, entity level, metric references, and date range. Use custom:<metric_uuid> for a custom metric. grain is daily or period. The response can also include supported provider metrics. Request
Response: HTTP 200
Use cursor and limit for more rows. A missing metric value stays null. Reads can include corrections from an active or failed import. See Import custom metrics for the app flow and Custom metric MCP tools for agent calls.