Skip to content

Errors and Limits

This page collects behavior that applies across the Partner API.

Every non-2xx response uses the same JSON shape:

{
"code": "EVENT_NOT_FOUND",
"message": "No event exists for that partner id",
"correlation_id": "<CORRELATION_ID>"
}

Branch on code, not message. Messages are for logs and operator visibility.

Send x-correlation-id when you have a trace ID:

Terminal window
curl -sS "$MESHI_BASE/auth" \
-H "Authorization: Bearer $MESHI_KEY" \
-H "x-correlation-id: partner-trace-001"

The response echoes the effective correlation ID in the x-correlation-id header and JSON body. Include it in support requests.

ConditionStatusCode
Missing or malformed bearer header401UNAUTHORIZED
Token does not resolve to an active key401UNAUTHORIZED
Disabled service account401ACCOUNT_DISABLED
Token is not an org-scoped service-account key403SERVICE_ACCOUNT_REQUIRED
Key lacks the required method scope403INSUFFICIENT_SCOPE
Request requires an org but none is available403PARTNER_ORG_REQUIRED
CodeTypical causeIntegration action
INVALID_JSONRequest body is not valid JSON.Fix serialization.
INVALID_PARTNER_KINDkind fails the documented pattern.Fix the kind value.
INVALID_PARTNER_IDPartner ID fails the documented pattern.Fix the ID value.
INVALID_IDEMPOTENCY_KEYMissing, empty, or too-long idempotency key.Generate a valid key.
INVALID_ATTENDEESEmpty attendees array or over the row cap.Fix or chunk the import.
DUPLICATE_ATTENDEE_IDSame attendee ID appears twice in one import payload.Deduplicate before sending.
PARTNER_ID_CONFLICTCreate attempted with an ID already mapped in your org.Fetch and confirm before continuing.
IDEMPOTENCY_KEY_CONFLICTSame key reused for a different event or operation.Use a fresh key.
PAYLOAD_TOO_LARGERequest body exceeds the byte limit.Split the request.
PARTNER_RATE_LIMIT_EXCEEDEDRequest window exhausted.Honor Retry-After.

Route-specific errors are listed in the endpoint reference.

Run-creating writes require idempotency_key:

  • PUT /events/:event_id/attendees:import
  • POST /events/:event_id/enrichment-runs
  • POST /events/:event_id/match-runs
  • POST /runs

Rules:

  1. Generate one key per logical operation.
  2. Reuse the same key for retries of that same operation.
  3. Do not reuse a key across different events or different logical operations.

First accepted use returns a created or accepted run. A replay in the same scope returns 200 with idempotent_replay: true. A conflicting reuse returns 409 IDEMPOTENCY_KEY_CONFLICT.

Async run status values:

StatusTerminal?Meaning
queuedNoAccepted but not started.
runningNoWork is in progress.
succeededYesCompleted without errors.
partialYesCompleted with per-item errors.
failedYesRun failed.

Poll GET /runs/:run_id until the status is terminal.

List endpoints use cursor pagination:

  • limit defaults to 50 and maxes at 100.
  • next_cursor is an opaque string or null.
  • Pass cursor=<next_cursor> verbatim.
  • Do not parse, decode, or construct cursors.
  • Ordering is documented per endpoint.

The default public contract is 600 requests per 60 seconds per API key. This limit can vary by environment or partner agreement.

When the limit is exceeded, the response is 429 PARTNER_RATE_LIMIT_EXCEEDED with a Retry-After header. Sleep for that many seconds before retrying. For repeated 429 or 5xx responses, use exponential backoff with jitter.

Two independent size guards apply:

LimitDefaultFailure
Request body size16 MiB413 PAYLOAD_TOO_LARGE
Attendees per import50,000 rows400 INVALID_ATTENDEES

For large rosters, split attendees into chunks. Use a distinct idempotency key for each chunk, and poll each chunk’s run independently.

webhook_url is accepted, stored, and echoed on run objects for forward compatibility. v0 does not deliver webhook callbacks. Do not build an integration that waits for a webhook; poll GET /runs/:run_id.