Skip to main content

Documentation Index

Fetch the complete documentation index at: https://archie.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

The REST API uses standard HTTP verbs for writes: POST to create, PATCH to update, DELETE to delete. Updates follow RFC 7396 JSON Merge Patch — only the fields you send are changed. The endpoints are auto-generated from your Data Model, so adding a field to a table extends the request and response schema automatically. The examples assume a students table with fields like firstName, email, age, isActive, and a city relationship.

Single record

Create

POST /api/rest/<table> with a JSON body. Returns 201 Created with the new record and a Location header.
curl -X POST "https://your-gateway.example.com/gw/api/rest/students" \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Alice",
    "email": "alice.jones@example.com",
    "age": 21,
    "isActive": true
  }'
{
  "data": {
    "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "firstName": "Alice",
    "email": "alice.jones@example.com",
    "age": 21,
    "isActive": true,
    "createdAt": "2025-12-15T14:30:00.000Z",
    "updatedAt": "2025-12-15T14:30:00.000Z"
  }
}
To skip the response body, send Prefer: return=minimal — you’ll get 201 Created with no body. To link to a related record, include the foreign key in the input:
{
  "firstName": "Alice",
  "email": "alice.jones@example.com",
  "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb"
}
For safe retries (network failures, timeouts), include an Idempotency-Key header — see Idempotency.

Update

PATCH /api/rest/<table>/<id> with the fields you want to change. Fields you don’t include are left alone.
curl -X PATCH "https://your-gateway.example.com/gw/api/rest/students/287cff0a-345b-4cca-9e9a-75a2161238fd" \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{
    "age": 23,
    "isActive": false
  }'
{
  "data": {
    "id": "287cff0a-345b-4cca-9e9a-75a2161238fd",
    "firstName": "James",
    "age": 23,
    "isActive": false,
    "updatedAt": "2025-12-15T14:45:00.000Z"
  }
}
To explicitly null a field, include it with a null value:
{
  "bio": null,
  "middleName": null
}
Both application/merge-patch+json and application/json are accepted as Content-Type.

Delete

DELETE /api/rest/<table>/<id>. Returns 204 No Content on success.
curl -X DELETE "https://your-gateway.example.com/gw/api/rest/students/287cff0a-345b-4cca-9e9a-75a2161238fd" \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id"

Bulk create

POST /api/rest/<table>/_bulk creates up to 100 records in one request.
curl -X POST "https://your-gateway.example.com/gw/api/rest/students/_bulk" \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "firstName": "Alice", "email": "alice@example.com", "age": 21 },
      { "firstName": "Bob", "email": "bob@example.com", "age": 25 }
    ],
    "transactionMode": "ALL_OR_NOTHING"
  }'

Transaction modes

ModeBehavior
ALL_OR_NOTHING (default)Single transaction. Any failure rolls back the whole batch.
BEST_EFFORTIndependent inserts. Failures are reported but don’t block other rows.
Pass transactionMode in the body, or as a query parameter (?mode=BEST_EFFORT).

Success — 201

{
  "data": {
    "success": true,
    "transactionMode": "ALL_OR_NOTHING",
    "totalRequested": 2,
    "totalSucceeded": 2,
    "totalFailed": 0,
    "items": [
      { "id": "f47ac10b-..." },
      { "id": "a1b2c3d4-..." }
    ],
    "errors": []
  }
}

Partial success in BEST_EFFORT — 207

{
  "data": {
    "success": false,
    "transactionMode": "BEST_EFFORT",
    "totalRequested": 3,
    "totalSucceeded": 2,
    "totalFailed": 1,
    "items": [
      { "id": "f47ac10b-..." },
      { "id": "c3d4e5f6-..." }
    ],
    "errors": [
      { "index": 1, "message": "Unique constraint violated: email already exists" }
    ]
  }
}

Rollback in ALL_OR_NOTHING — 422

When any row fails in ALL_OR_NOTHING mode, the API returns 422 and totalSucceeded is 0 — none of the rows were inserted.

Bulk delete

DELETE /api/rest/<table>/_bulk removes multiple records in one request.

By ids (single primary key)

curl -X DELETE "https://your-gateway.example.com/gw/api/rest/students/_bulk" \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id" \
  -H "Content-Type: application/json" \
  -d '{
    "ids": [
      "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
    ]
  }'

By filters (composite primary keys)

curl -X DELETE "https://your-gateway.example.com/gw/api/rest/orderProducts/_bulk" \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": [
      { "orderId": "order-1", "productId": "prod-1" },
      { "orderId": "order-2", "productId": "prod-2" }
    ],
    "transactionMode": "ALL_OR_NOTHING"
  }'
You can’t mix ids and filters in the same request. Composite primary keys require filters.

Update by filter

PATCH /api/rest/<table> (no id in the path) updates every record matching the filter parameters. Useful for batch operations like “mark all expired”.
curl -X PATCH "https://your-gateway.example.com/gw/api/rest/students?isActive=equals.false&age=lt.18" \
  -H "Authorization: Bearer archie_YOUR_API_KEY" \
  -H "X-Project-ID: your-project-id" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{
    "status": "inactive",
    "notes": "Auto-deactivated: underage"
  }'
At least one filter parameter is required. A PATCH to /<table> with no filters returns 422 Unprocessable Entity — this is intentional, to prevent accidentally updating every row in the table.
The filter syntax matches the filtered list query.

Limits

SettingDefault
Max items in a bulk request100
Max field selection depth3
Max relations per query10
Exceeding any limit returns 422 Unprocessable Entity with details.

Error responses

Errors follow the Problem Details format with Content-Type: application/problem+json.
{
  "type": "/errors/validation-failed",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "One or more fields failed validation",
  "instance": "/api/rest/students",
  "errors": [
    { "field": "email", "rule": "required", "message": "The field 'email' is required" }
  ]
}
For the full status-code reference and how to handle each one, see Error handling.

Permissions

Every mutation is checked against Role-Based Access. Field-level write rules apply too — fields a role isn’t allowed to write are rejected.

FAQ

Use PATCH. Archie’s update endpoints implement RFC 7396 Merge Patch semantics — only the fields you send are changed. There’s no full-record PUT replacement variant.
Send the same Idempotency-Key header on the retry. The API will return the cached response from the first call instead of creating a duplicate. See Idempotency.
BEST_EFFORT mode reports per-row outcomes — some succeeded, some didn’t. The body’s errors array tells you which rows failed and why. For all-or-nothing semantics, switch to ALL_OR_NOTHING.
The API returns 422 Unprocessable Entity with the offending field name. Unknown fields are not silently ignored.