Skip to content

Endpoints

The generated REST surface for every resource you publish.

Snaapi automatically generates a full set of REST API endpoints for every enabled resource. All endpoints live under the /v1/:resourceName namespace and authenticate via an Authorization: Bearer <key> header. Responses follow the JSON:API specification.

Base URL

All resource endpoints follow the pattern:

https://your-api.snaapi.cloud/v1/:resourceName

Replace :resourceName with the name of the resource you defined (for example, posts, comments, orders).

List records

Retrieve a paginated list of records, optionally filtered and sorted.

GET /v1/:resourceName

Response (200):

{
  "data": [
    {
      "type": "posts",
      "id": "uuid",
      "attributes": {
        "title": "Hello",
        "created_at": "2026-01-01T00:00:00Z",
        "updated_at": "2026-01-01T00:00:00Z"
      }
    }
  ],
  "meta": {
    "total": 42
  },
  "links": {
    "self": "/v1/posts?page[offset]=0&page[limit]=50",
    "first": "/v1/posts?page[offset]=0&page[limit]=50",
    "next": "/v1/posts?page[offset]=50&page[limit]=50"
  }
}

See Filtering and pagination for query parameter details.

Try it:

curl https://your-api.snaapi.cloud/v1/posts \
  -H "Authorization: Bearer sna_your-api-key"

Get single record

Retrieve a single record by its ID.

GET /v1/:resourceName/:id

Response (200):

{
  "data": {
    "type": "posts",
    "id": "uuid",
    "attributes": {
      "title": "Hello",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T00:00:00Z"
    }
  }
}

Create record

Create a new record. Send a JSON body with the fields defined on the resource.

POST /v1/:resourceName

Request body:

{
  "title": "My New Post",
  "body": "Content goes here"
}

Response (201):

{
  "data": {
    "type": "posts",
    "id": "generated-uuid",
    "attributes": {
      "title": "My New Post",
      "body": "Content goes here",
      "created_at": "2026-01-01T00:00:00Z",
      "updated_at": "2026-01-01T00:00:00Z"
    }
  }
}

Try it:

curl -X POST https://your-api.snaapi.cloud/v1/posts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sna_your-api-key" \
  -d '{ "title": "Hello World", "body": "My first post" }'

Update record (full replace)

Replace all fields on an existing record.

PUT /v1/:resourceName/:id

Request body:

{
  "title": "Updated Title",
  "body": "Updated content"
}

Update record (partial)

Update only the specified fields on an existing record.

PATCH /v1/:resourceName/:id

Request body:

{
  "title": "Updated Title Only"
}

Delete record

Delete a record by ID. If the resource has enableSoftDelete: true, the record is soft-deleted (a deleted_at timestamp is set) rather than permanently removed.

DELETE /v1/:resourceName/:id

Response (204 No Content): No response body.

Other endpoints

Method Path Description
GET /v1/:resourceName/stream Server-Sent Events subscription
GET /v1/:resourceName/schema JSON Schema for the resource

The full OpenAPI spec covering every resource is served from /openapi.json and /openapi.yaml at the root of your API. See OpenAPI.

Authentication

Requests carry an API key in the Authorization: Bearer <key> header. The role attached to the caller is evaluated against the resource's permissions before the request is served.

Response classes

All responses follow the JSON:API specification and use Content-Type: application/vnd.api+json.

Success responses

Successful responses wrap resource objects in a top-level data key. Each resource object includes type, id, and attributes. Status 200 for reads and updates, 201 for creates, and 204 when no content is returned (for example, after a delete).

Error responses

Errors are returned as an array of JSON:API error objects under a top-level errors key.

{
  "errors": [
    {
      "status": "404",
      "code": "RESOURCE_NOT_FOUND",
      "title": "Resource not found",
      "detail": "The requested resource does not exist or is disabled"
    }
  ]
}

Validation errors

Returned with status 400 when request data fails validation. Each entry in the errors array identifies the problematic field using a JSON Pointer in source.

{
  "errors": [
    {
      "status": "400",
      "code": "INVALID_RESOURCE_DATA",
      "title": "Validation failed",
      "detail": "Expected string, received number",
      "source": { "pointer": "/data/attributes/title" }
    }
  ]
}

Error codes

Client errors

Code Status Description
NO_RESOURCE_NAME 400 Missing resource name in the URL
INVALID_JSON 400 Request body is not valid JSON
INVALID_FIELDS 400 Field names not allowed for the user's role
INVALID_QUERY_PARAMS 400 Malformed query parameters
INVALID_RESOURCE_DATA 400 Data fails schema validation
RELATION_REFERENCE_ERROR 400 Referenced record not found in foreign table
RESOURCE_NOT_FOUND 404 Resource does not exist or is disabled
RESOURCE_DISABLED 404 Resource is explicitly disabled
FORBIDDEN 403 User's role lacks permission for this action or resource
KEY_PERMISSION_DENIED 403 API key does not have permission for this action
ADMIN_TOKEN_NOT_ALLOWED 403 Admin tokens cannot create or update via resource endpoints

Server errors

Code Status Description
RESOURCE_FETCH_ERROR 500 Failed to fetch records
RESOURCE_STORE_ERROR 500 Failed to create record
RESOURCE_UPDATE_ERROR 500 Failed to update record
RESOURCE_DELETE_ERROR 500 Failed to delete record
RESOURCE_FIND_ERROR 500 Failed to find record
RESOURCE_SCHEMA_ERROR 500 Failed to retrieve schema

Admin token restrictions

Admin tokens are designed for management operations. On resource endpoints, they are restricted to read and delete operations only.

Operation Method Allowed
List / Read GET Yes
Create POST No
Update (full) PUT No
Update (partial) PATCH No
Delete DELETE Yes

Attempting to create or update records with an admin token returns a 403 error with code ADMIN_TOKEN_NOT_ALLOWED. Use the dedicated admin API endpoints for write operations instead.