Ask what happened to the invitations you created — outstanding, accepted, expired or revoked — by your own reference, your batch key, the email, or our code. Poll it on whatever schedule suits your reconciliation.
Every request needs a bearer token. You only ever see invitations your own organisation created — that holds for every lookup, including code, which is our identifier rather than yours.
| Field | Type | Required | Description |
|---|---|---|---|
| Authorization | string | required | Bearer token obtained from POST /api/third-party/v1/auth/token, e.g. "Bearer eyJhbGci...". |
| Field | Type | Required | Description |
|---|---|---|---|
| reference | string | optional | Your own identifier for one invitation, as you supplied it. The most direct way to ask about a single invitation. |
| requestId | string | optional | The batch key you sent when creating invitations. Returns every invitation created under it. |
| string | optional | The address the invitation was sent to. Case-insensitive. | |
| code | string | optional | Our invite code. Only ever returns invitations you created. |
| state | string | optional | One of "outstanding", "accepted", "expired", "revoked". Narrows to that state. |
| limit | number | optional | How many to return, 1–200. Defaults to 50. Above 200 is rejected, not silently reduced. |
| cursor | string | optional | Pass the nextCursor from the previous response for the following page. Omit for the first. |
state has exactly four values — outstanding, accepted, expired, revoked — and they will not change. The status field beside it is our finer-grained internal value, which we may add to. There is no declined state: nothing lets a traveller refuse an invitation, so someone who ignores one leaves it outstanding until it expires.
Nothing about the person. You see that an invitation was accepted and when, never who the traveller turned out to be — no account id, no username, not a masked address. You already hold the email you sent to and the reference you chose.
# One invitation, by your own reference
curl -X GET "https://kicbak.co/api/third-party/v1/kicbak/invites?reference=booking-88213" \
-H "Authorization: Bearer YOUR_TOKEN"
# Everything still outstanding, 100 at a time
curl -X GET "https://kicbak.co/api/third-party/v1/kicbak/invites?state=outstanding&limit=100" \
-H "Authorization: Bearer YOUR_TOKEN"Every response is JSON with a status field (1 success, 0 failure). Failures also carry a code your error handler can branch on — it never changes if we reword message.
{
"status": 1,
"message": "1 invitation retrieved",
"data": {
"invites": [
{
"code": "K7XQ2M9P",
"reference": "booking-88213",
"requestId": "batch-2026-08-19-0001",
"state": "accepted",
"status": "GRANTED",
"invitedEmail": "ada@example.com",
"invitedName": "Ada",
"deliveryMethod": "EMAIL",
"rewardSpecKind": "FIXED_KIC",
"rewardKicAmount": 350,
"resolvedKicAmount": 350,
"createdAt": "2026-08-19T10:00:00.000Z",
"expiresAt": null,
"acceptedAt": "2026-08-19T14:22:11.000Z"
}
],
"nextCursor": null
}
}| Status | Code | Meaning |
|---|---|---|
| 400 | — | A query parameter is out of range — e.g. a limit above 200. The message names it. |
| 401 | UNAUTHORIZED | No readable credential, or a token that doesn't decode/validate. |
| 401 | TOKEN_EXPIRED | Token aged out. Re-exchange the same client_key/client_secret and retry. |
| 401 | CREDENTIAL_ROTATED | This token was minted under a secret that has since been rotated. Exchange your new secret. |
| 401 | CREDENTIAL_EXPIRED | The credential itself is past its own expiry — re-exchanging will not help; request a new credential. |
| 401 | CLIENT_INACTIVE | The client has been deactivated. |
| 403 | NOT_ORGANIZATION | Client is not organisation-owned — only organisation clients can call this endpoint. |
| 503 | SANDBOX_UNAVAILABLE | You are using a sandbox credential and the sandbox environment is temporarily unavailable on our side. Retry shortly; production credentials are unaffected. |
| 429 | — | More than the configured hourly limit (default 600) from this client. |
| 500 | INTERNAL_ERROR | Unexpected server error. Safe to retry. |
When more results exist, data.nextCursor is a string; pass it back as cursor. When it is null you have reached the end. Keep paging until it is null even if a page comes back empty.