API Docs

API Authentication

Authenticate API requests with the X-API-Key header:

X-API-Key: csb_live_your_token_here

API keys are issued per user. Key management endpoints support either session auth (cookie) or API key auth, except validate which requires an API key.

Endpoints

  • GET /api/v1/api_keys
  • POST /api/v1/api_keys
  • DELETE /api/v1/api_keys/:id
  • POST /api/v1/api_keys/validate

GET /api/v1/api_keys

Lists keys for the authenticated user (newest first).

curl -X GET "https://cases.shipmentbot.com/api/v1/api_keys" \
  -H "Accept: application/json" \
  -H "X-API-Key: csb_live_your_token_here"
{
  "api_keys": [
    {
      "id": 24,
      "name": "Zapier integration",
      "masked_token": "********17a0cb9d",
      "expires_at": "2027-01-01T00:00:00.000Z",
      "last_used_at": "2026-03-05T17:54:14.000Z",
      "created_at": "2026-03-01T12:03:20.000Z"
    },
    {
      "id": 18,
      "name": "Data sync worker",
      "masked_token": "********de8ab124",
      "expires_at": null,
      "last_used_at": null,
      "created_at": "2026-02-21T08:22:44.000Z"
    }
  ]
}

POST /api/v1/api_keys

Creates an API key. The plaintext token is returned once in the response as api_key.token.

curl -X POST "https://cases.shipmentbot.com/api/v1/api_keys" \
  -H "Content-Type: application/json" \
  -b "_case_study_buddy_session=YOUR_SESSION_COOKIE" \
  -d '{
    "name": "CI automation key",
    "expires_at": "2027-01-01T00:00:00Z"
  }'
{
  "api_key": {
    "id": 25,
    "name": "CI automation key",
    "masked_token": "********c8f43d2a",
    "expires_at": "2027-01-01T00:00:00.000Z",
    "last_used_at": null,
    "created_at": "2026-03-05T18:12:53.000Z",
    "token": "csb_6b8a6f38a0b7..."
  }
}

Create Validation Error (422)

{
  "errors": [
    "Name can't be blank"
  ]
}

DELETE /api/v1/api_keys/:id

Revokes a key owned by the authenticated user.

curl -X DELETE "https://cases.shipmentbot.com/api/v1/api_keys/25" \
  -H "X-API-Key: csb_live_your_token_here"

Successful response: 204 No Content.

Delete Not Found Error (404)

{
  "error": "API key not found."
}

POST /api/v1/api_keys/validate

Checks whether a key is valid and returns the owning user id + key metadata.

curl -X POST "https://cases.shipmentbot.com/api/v1/api_keys/validate" \
  -H "Accept: application/json" \
  -H "X-API-Key: csb_live_your_token_here"
{
  "valid": true,
  "user_id": 9,
  "api_key": {
    "id": 24,
    "name": "Zapier integration",
    "masked_token": "********17a0cb9d",
    "expires_at": "2027-01-01T00:00:00.000Z",
    "last_used_at": "2026-03-05T17:54:14.000Z",
    "created_at": "2026-03-01T12:03:20.000Z"
  }
}

Unauthorized Error (401)

Missing/invalid/expired keys across API endpoints return a consistent JSON:API-style error envelope.

{
  "data": null,
  "included": [],
  "links": {
    "self": "https://cases.shipmentbot.com/api/v1/campaigns"
  },
  "meta": {},
  "errors": [
    {
      "status": "401",
      "title": "Unauthorized",
      "detail": "API key is invalid or expired."
    }
  ]
}

Rotation Pattern

  1. Create a new key with POST /api/v1/api_keys.
  2. Deploy new key to clients.
  3. Validate with POST /api/v1/api_keys/validate.
  4. Delete old key with DELETE /api/v1/api_keys/:id.