API conventions
Three rules hold for every endpoint: writes can be retried safely, lists page with cursors, and errors always have the same shape.
Idempotency keys
Send an Idempotency-Key header with any POST. If the same key arrives again within 24 hours, you get the original result back and the work is not done twice. Use a new UUID for each distinct action.
curl -X POST "$BASE/conversations/cnv_7Hq2Lm/reply" \
-H "Authorization: Bearer $GRIPZ_API_KEY" \
-H "Idempotency-Key: 6f1c2a9e-4b7d-4e0a-9a3e-2d5b8c1f7a40" \
-H "Content-Type: application/json" \
-d '{ "body": "Your refund is on its way." }'Cursors
List endpoints return 50 items by default and 200 at most. Pass next_cursor back as cursor to get the next page. Cursors are opaque, so do not parse or build them.
GET /v1/contacts?limit=50&cursor=cur_9aK2mQ
{
"data": [ { "id": "ct_9d3m", "name": "Elena Marchetti" } ],
"has_more": true,
"next_cursor": "cur_Lp41xT"
}Error format
Every error has a type, a stable code, a message written for a person, and a request ID you can quote to support.
{
"error": {
"type": "invalid_request_error",
"code": "parameter_invalid",
"message": "limit must be between 1 and 200.",
"param": "limit",
"doc_url": "https://developers.gripz.example/rest/conventions#cursors",
"request_id": "req_8F2KQ41Z"
}
}| type | The family: invalid_request_error, authentication_error, permission_error, rate_limit_error or api_error. |
|---|---|
| code | A stable string to branch on in code. Codes are never renamed within a version. |
| request_id | Also sent as the Gripz-Request-Id header on every response, including successes. |