Skip to navigation

Customers

Provision an end customer and manage its lifecycle

A Customer represents one of your end customers. Create one per tenant, store its id, and send it as customer on requests, or skip storing anything and address it by your own ID. Its policies, keys, and budget are separate sub-resources.

Create a customer

name and origin_id are required, and key_usage_default is optional. origin_id is your identifier for the tenant, unique in your organization and immutable.

cURL
curl -X POST https://api-gateway.merge.dev/v1/customers \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Acme", "origin_id": "acme-corp", "key_usage_default": "PREFER_BYOK" }'

The response includes the id. A duplicate origin_id returns 409.

Address customers by your own ID

Send your origin_id in the X-Merge-Customer-Origin-Id header instead of the Customer’s id. It works on every endpoint that accepts customer and needs no mapping table on your side.

cURL
curl https://api-gateway.merge.dev/v1/responses \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY" \
-H "X-Merge-Customer-Origin-Id: acme-corp" \
-H "Content-Type: application/json" \
-d '{ "input": [{"type": "message", "role": "user", "content": "Hello"}] }'

If no customer has that origin_id yet, Gateway creates one with your organization’s defaults (name set to the origin_id) and serves the request. Later requests reuse it. A deleted customer’s origin_id stays blocked with 403 rather than being created again; create it explicitly with POST /v1/customers to reuse it.

To give the customer its own key by origin_id, see Mint by your own ID.

Sending both customer and the header is allowed only when they name the same customer. With a customer API key, the header must name the key’s own customer and never creates one.

Sync customers in bulk

PUT /v1/customers/batch creates or updates up to 100 customers by origin_id in one call. Each item takes origin_id and optional name (defaults to the origin_id on create) and key_usage_default. Fields you omit are left unchanged on existing customers.

cURL
curl -X PUT https://api-gateway.merge.dev/v1/customers/batch \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "customers": [
{ "origin_id": "acme-corp", "name": "Acme" },
{ "origin_id": "globex", "key_usage_default": "BYOK_ONLY" }
] }'
{
"results": [
{ "origin_id": "acme-corp", "id": "9f8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d", "status": "created" },
{ "origin_id": "globex", "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "status": "updated" }
]
}

status is created, updated, unchanged, or error. Items are independent: an error item carries error.status_code, error.code (such as customer_limit_reached or origin_id_conflict), and error.message, and doesn’t undo the others. A duplicate origin_id within one batch, an empty list, or more than 100 items returns 422.

Look up a customer

Resolve an origin_id with GET /v1/customers?origin_id=acme-corp, which returns the list envelope (results, next, previous) with the one match or empty results. Without the filter it lists every customer, paginated with limit and cursor. GET /v1/customers/{customer_id} returns one customer.

Update, deactivate, or delete

PATCH /v1/customers/{customer_id} changes name, key_usage_default, or status. INACTIVE stops serving the customer’s traffic but keeps its configuration; ACTIVE resumes.

cURL
curl -X PATCH https://api-gateway.merge.dev/v1/customers/{customer_id} \
-H "Authorization: Bearer $MERGE_GATEWAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "INACTIVE" }'

DELETE /v1/customers/{customer_id} is permanent: it revokes the customer’s API keys, policies, and vendor keys, and later requests naming its ID return 403 instead of falling back to your organization’s defaults.

Reference

FieldTypeDescription
idUUIDSend as customer on requests
origin_idstringYour ID for the customer, 1 to 255 characters, unique, can’t be changed. Send it in X-Merge-Customer-Origin-Id to address the customer.
namestringDisplay name, up to 255 characters
key_usage_defaultenumUSE_ANY, PREFER_BYOK, BYOK_ONLY, or CUSTOMER_ONLY. Unset inherits your organization’s default. See key usage modes.
statusenumACTIVE or INACTIVE. Requests for an inactive customer return 403.
routing_policies, budgets, byok_configurationslist of UUIDsIDs of the customer’s sub-resources. Read each from its own endpoint.
created_at, modified_atdatetimeTimestamps

A customer API key can read its own customer and change only name; any other field returns 403 customer_scoped_key_forbidden_field.

An organization can have up to 100,000 customers. Creating one past that returns 409 customer_limit_reached from the customers API, and 403 customer_limit_reached when X-Merge-Customer-Origin-Id would create it.

Next steps