Skip to main content
Log in

Partner API

Authenticate to the correct region, import data, and retrieve metric definitions and customer health evaluations.

Use the Partner API to integrate Cust with your own systems. Its interactive reference contains endpoint schemas, required fields, and response examples:

Authentication and region

Generate an API key in Settings → API keys. Use the API host for the region containing your workspace.

Send the key in the Authorization header with the Token scheme:

Authorization: Token YOUR_API_KEY

Keep the key in your server's secret storage. Do not put it in a public page, browser application, or shared documentation.

API keys belong to their creator in the workspace. Deactivating that member, including through SCIM, revokes the keys they created for that workspace. Reactivating the member does not restore revoked keys; create replacements and update any affected integrations.

Available resources

ResourceUse
Bulk importsSubmit an import job and inspect its processing status and results.
File uploadsRequest the upload details needed for a file-based import.
MetricsList or retrieve the metric definitions available to your workspace.
Health evaluationsRetrieve recorded company health evaluations and their changes over time.

Endpoints are under /v1/. The machine-readable OpenAPI schema is available at /schema/ on either regional host. Follow the current reference for upload and import request bodies; importing a file is an asynchronous operation, so check the job result after submission.

Import your first CSV

The complete flow has four requests: request a file upload, send the file to storage, create an import job, and poll that job. The downloadable Python client performs this flow with Python 3.9 or later and no additional packages.

1. Prepare two company rows

Download the two-row company CSV and replace its values with the accounts you want to import:

external_id,name,website,industry
pfizer,Pfizer,https://www.pfizer.com,Pharmaceuticals
cloudflare,Cloudflare,https://www.cloudflare.com,Cloud infrastructure

Use your stable external IDs. An existing company with the same External ID can be updated by an import. Keep the UTF-8 CSV header names unchanged. For more fields or other record types, download the current workspace's template from Data import.

2. Run the client

Save the Python client and CSV in the same directory. Make your API key available as the CUST_API_KEY environment variable through your secret manager or a private terminal prompt, then run:

python3 partner-api-import.py \
  --region eu \
  --resource company \
  --csv partner-api-companies.csv \
  > import-result.json

Use --region us for a US workspace. The script prints the job ID and progress to the terminal, then saves the finished job response in import-result.json. A clean processing result exits with code 0; a failed or skipped-row result exits with 2 for review. Request errors and polling timeouts exit with 1.

The script sends these requests:

StepRequestRequired content
Request uploadPOST /v1/file-uploads/JSON with file_name and content_type: "text/csv".
Upload bytesPOST to the returned upload_urlMultipart form containing every returned upload_fields value, then the CSV in a file part. Complete it before expires_at.
Create importPOST /v1/bulk-imports/JSON with resource_type: "company" and source_file set to the upload record's id.
Check jobGET /v1/bulk-imports/{id}/Poll while status is pending or processing.

Use Authorization: Token ... for the Partner API requests. The storage upload uses its returned signed form fields, so the client sends it without the Cust authorization header. The storage request is a multipart POST, not a raw file upload or PUT.

A polling timeout does not cancel the import. Resume checking the same job instead of creating another one:

python3 partner-api-import.py --region eu --job-id 123 --timeout 600 \
  > import-result.json

3. Check processing and the actual record

A finished response includes the job's status, result_message, started_at, and completed_at. Read the message even when status is completed: the processing lifecycle can finish with row validation errors or skipped records.

A clean two-row import reports, for example:

{
  "id": 123,
  "status": "completed",
  "result_message": "Import completed successfully. Total rows processed: 2. New records created: 2."
}

Open Settings → Data import to find the job and review its result. Then open Pfizer in Companies and compare its External ID, website, and industry with the CSV. Repeat for Cloudflare. A job response reports processing; checking the resulting company confirms that the intended data is present.

The Partner API currently exposes metric definitions and health evaluations, but no company-record or metric-reading retrieval endpoint. Verify those imported values in Cust.

Import metric readings

Create the company-level weekly_active_seats metric first, as described in the warehouse recipe. Download the two-row metric CSV and adjust its company references, values, and timestamps, then run:

python3 partner-api-import.py \
  --region eu \
  --resource metric_data \
  --csv partner-api-metric-data.csv \
  > metric-import-result.json

For metric_data, each row uses company or contact, metric_slug, value, and timestamp, with an optional note. Use a numeric Cust ID or extid- followed by the matching External ID. Supply one entity per row, and use an ISO 8601 timestamp with a timezone, such as 2026-09-22T00:00:00Z.

Metric definitions and referenced companies or contacts must already exist. The same entity, metric, and timestamp identify the same reading, so a corrected import can update its value. Open the company's metric chart and compare the individual reading with the source row.

Troubleshoot an import

ResultWhat to do
Storage rejects an expired signed uploadRequest new upload details and resend all returned form fields with the file. Create the import only after the storage upload succeeds.
Only CSV files are supported.Request the upload with content_type: "text/csv", then upload a UTF-8 CSV. A different declared content type is rejected when creating the import.
completed with Import failed with errorsRead the validation details in result_message, correct the relevant rows, and check which valid rows were already imported.
Skipped metric rowsConfirm the referenced company or contact exists and its ID matches. Check the metric API name and that each row supplies one entity.
A timeout after submitting a create requestCheck Data import or GET /v1/bulk-imports/ for the job before resubmitting. Use --job-id once you have its ID.

Keep IDs stable when retrying corrected rows. Valid rows can be saved even when other rows fail. The API's result message is shortened to 1,000 characters, so resolve reported errors and check the next result when a large file has many failures.

Read health evaluations

Health evaluations are read-only through this API. You can filter by company, creation time, current or previous score, and whether the score changed.

For example, to retrieve changes for a company identified by your external ID on the EU deployment:

curl --get 'https://partner-api.cust.co/v1/health-evaluations/' \
  --header "Authorization: Token ${CUST_API_KEY}" \
  --data-urlencode 'company=extid-YOUR_COMPANY_ID' \
  --data-urlencode 'changed=true'

Use a numeric Cust company ID or the extid- prefix followed by its external ID. Creation-time filters include created_at_gte, created_at_gt, created_at_lte, and created_at_lt. Use the score values defined in the API schema.

Results use cursor pagination. Follow the response's next URL until it is empty. The first evaluation is treated as a change because there is no previous score.

To refresh an account's health in the product, use the company's health controls. A read request to this endpoint does not run a new evaluation.

For a manual file upload through the product, see Data import.