Authentication
Authenticate partner requests with a partner master key.
The partner API uses your partner master key. It starts with mk_live_ and lets you act on every workspace you manage: each route names the client it works on with partner_workspace_id in its path, except creating and listing workspaces, which name no client in their path. The key alone identifies you, no other identifier is needed.
Header
Send the master key in the Authorization header:
Authorization: Bearer <YOUR_MASTER_KEY>Example request
curl "https://api.getsillage.com/api/v3/partner/workspaces/ws_123/lists?page_size=5" \
-H "Authorization: Bearer $SILLAGE_MASTER_KEY"Status codes
| Status | Meaning |
|---|---|
| 200 | The request succeeded. |
| 401 | The master key is missing or invalid. |
| 403 | The workspace is blocked, so no run can be launched. |
| 404 | No workspace found for this partner_workspace_id, or the resource does not exist. |
| 405 | The path exists but not with this method. The Allow header lists the methods it takes. |
| 409 | The request conflicts with the current state of a resource. |
| 422 | The request is refused: the body is not valid JSON, or a field, a parameter, a value or a cursor is not valid, or not known. |
| 429 | Rate limit exceeded. |
| 500 | An unexpected server error occurred. |
Error model
Every error is an RFC 9457 problem document, sent with Content-Type: application/problem+json. It has these fields:
| Field | Description |
|---|---|
| type | Always about:blank. |
| title | A short name for the problem, the same every time it happens. |
| status | The HTTP status code. |
| code | A stable identifier for the problem, such as invalid_body. Use it, not title or detail, to tell one problem from another. See Error codes. |
| detail | What went wrong this time. |
| instance | The path of the request. |
| errors | Only on 422, and absent on a 422 that names no field: the fields at fault, each with the list of what is wrong with it. |
| signal_setup_ids | Only on the list_persona_setup_conflict 409: the IDs of the signal setups that block the change. |
{
"type": "about:blank",
"title": "Unprocessable Entity",
"status": 422,
"code": "invalid_body",
"detail": "Invalid request body",
"instance": "/api/v3/partner/workspaces/ws_123/contents/query",
"errors": {
"limit": ["must be at most 100"]
}
}An error about the request as a whole, or about several fields together, such as a missing body, is named _root. An unknown field is named in errors, under its own name:
{
"type": "about:blank",
"title": "Unprocessable Entity",
"status": 422,
"code": "invalid_body",
"detail": "Invalid request body",
"instance": "/api/v3/partner/workspaces/ws_123/contents/query",
"errors": {
"keyword": ["Unknown field: keyword"]
}
}Input is never silently replaced by a default: an unknown field, parameter or value, an invalid date, or a cursor that does not belong to the request is refused with 422. Only a body sent with GET or DELETE is ignored.
Error codes
The code of a problem is one of these values. Branch on it, never on title or detail.
| Status | Code | When |
|---|---|---|
| 401 | invalid_master_key | The master key is missing, malformed, revoked or invalid. |
| 403 | workspace_blocked | The workspace is blocked, so no run can be launched. |
| 404 | not_found | The resource named in the path does not exist. |
| 404 | partner_workspace_not_found | No workspace of yours has this partner_workspace_id, or it was deleted. |
| 404 | route_not_found | No route matches the path. |
| 405 | method_not_allowed | The path exists but not with this method. The Allow header lists the methods it takes. |
| 409 | partner_busy | A workspace is being created or restored for you right now. Retry in a moment. |
| 409 | run_in_progress | A run of this signal setup is still in progress. |
| 409 | setup_disabled | The signal setup is disabled. |
| 409 | last_list_of_tier | The list is the only one of its kind for its persona (for a prospect list, of its tier), so it cannot be deleted or archived. |
| 409 | list_in_use | A signal setup still uses the list. |
| 409 | smart_list | Smart lists are managed in the app: their members cannot be added or removed through the API. |
| 409 | tag_taken | Another persona of the workspace already uses this tag. |
| 409 | template_unavailable | The signal template is archived, so no signal can be set up from it. |
| 409 | list_persona_conflict | The list is attached only to personas other than the signal setup's persona. |
| 409 | list_persona_setup_conflict | Changing the personas of a list would leave signal setups on a list that is not attached to their persona. signal_setup_ids names them. |
| 409 | no_covered_account | Every account the signal setup would check has monitoring turned on but unpaid. Nothing was started. |
| 409 | no_monitored_account | No account the signal setup would check is monitored. Nothing was started. |
| 409 | conflict | The request conflicts with the current state of a resource. |
| 422 | invalid_body | The body is not valid: a field is missing, has the wrong type or value, or is not known. |
| 422 | invalid_query | A query parameter is not valid or not known. |
| 422 | invalid_url_params | A value in the path is not valid. |
| 422 | invalid_json | The body is not valid JSON. |
| 422 | body_required | The route needs a JSON body and none was sent. |
| 422 | invalid_reference | An ID in the body or in a filter does not match a resource of your workspace. |
| 422 | invalid_date_range | A _from date is after its _to date. |
| 422 | persona_incomplete | The workspace has no persona, or its persona is missing something the request needs. |
| 422 | persona_required | The workspace has several personas, so the request must say which one with persona_id. |
| 422 | discovery_needs_job_titles | The signal run needs job titles, on the signal setup or on the persona. Nothing was started. |
| 422 | launch_not_possible | The signal setup cannot be launched as configured, for example it has no list or no keywords. Nothing was started. |
| 429 | rate_limited | Too many requests. The Retry-After header tells you how many seconds to wait. |
| 500 | internal_error | An unexpected error on our side. |
New codes may be added; for a code you don't know, act on the HTTP status.
Common response headers
Every response includes:
| Header | Description |
|---|---|
| X-Request-Id | Request UUID, to quote when you contact support. |
| X-Response-Time | How long the server took to answer. |
| X-RateLimit-Limit | Maximum number of requests allowed in the time window. |
| X-RateLimit-Remaining | Requests left in the current window. |
| X-RateLimit-Reset | When the window resets, as a Unix timestamp in milliseconds. |
A 429 response also carries Retry-After, the number of seconds to wait before you retry.
Security
Treat master keys like passwords
Store them on your servers, never in a browser or a mobile app, and rotate a key when someone who had access to it leaves your organization or when it may have been copied.