Docs·UnderPeaks

API Reference · Endpoints

Endpoints

Jump to: Hosted · Self-Hosted (Core)

Hosted

Base path:

/api-public/v1/PROJECT_ID/builder/MODEL_NAME

Every request requires authentication — see Authentication. Records are scoped to your tenant and project.

List records

GET /api-public/v1/PROJECT_ID/builder/MODEL_NAME

Any query parameter is passed through as a filter.

Response 200:

{ "data": [ { "field": "value" } ] }

Get a single record

GET /api-public/v1/PROJECT_ID/builder/MODEL_NAME/RECORD_ID

Response 200:

{ "data": { "field": "value" } }

If no record matches, the response is still 200 with a null data value, rather than a 404.

Create a record

POST /api-public/v1/PROJECT_ID/builder/MODEL_NAME Content-Type: application/json

{ "title": "New Product", "price": 29.99 }

Payloads are capped at 1MB (413 if exceeded).

Response 201:

{ "data": { "field": "value" } }

Update a record

PUT /api-public/v1/PROJECT_ID/builder/MODEL_NAME/RECORD_ID Content-Type: application/json

{ "price": 24.99 }

Payloads are capped at 1MB (413 if exceeded).

Response 200:

{ "success": true }

Delete a record

DELETE /api-public/v1/PROJECT_ID/builder/MODEL_NAME/RECORD_ID

Response 200:

{ "success": true }

Rate limits

Limits scale with your plan. Exceeding it returns an error response with your current plan name, limit, and an upgrade link.

Self-Hosted (Core)

Base path:

/api-public/v1/PROJECT_ID/TABLE_NAME

Every request requires the X-API-Key header — see Authentication. Records are automatically scoped to your project.

List records

GET /api-public/v1/PROJECT_ID/TABLE_NAME

Query parameters:

ParameterTypeDescription
pagenumberPage number. Default 1.
limitnumberResults per page. Default 20, capped at 100.
searchstringCase-insensitive substring match across all string fields.
sort_fieldstringColumn to sort by.
sort_dirstringasc or desc. Default asc.
any other keystringExact-match filter on that column, e.g. ?status=active.

Response 200:

{
  "records": [ { "prod_id": "value", "title": "value", "price": 24.99 } ],
  "total": 42,
  "page": 1,
  "limit": 20,
  "pages": 3
}

Columns marked hidden: true on the model are stripped from every record — see Field Types.

Get a single record

GET /api-public/v1/PROJECT_ID/TABLE_NAME?id=RECORD_ID

Response 200:

{ "record": { "prod_id": "value", "title": "value" } }

Returns 404 if no record matches id.

Create a record

POST /api-public/v1/PROJECT_ID/TABLE_NAME Content-Type: application/json

{ "title": "New Product", "price": 29.99 }

project_id, created_at, and updated_at are set by the server on every insert.

Response 201:

{ "success": true, "record": { "title": "New Product", "price": 29.99 } }

Update a record

PATCH /api-public/v1/PROJECT_ID/TABLE_NAME Content-Type: application/json

{ "id": "the-record-id", "id_column": "prod_id", "price": 24.99 }
FieldRequiredDescription
idYesThe value to match. 400 if missing.
id_columnNoThe column id is matched against. Defaults to id — set this explicitly if the model's primary key isn't literally named id.

Response 200:

{ "success": true, "record": { "field": "value" } }

Delete a record

DELETE /api-public/v1/PROJECT_ID/TABLE_NAME Content-Type: application/json

{ "id": "the-record-id" }

id is required, returns 400 if missing.

Known limitation: unlike Update, Delete does not currently accept id_column — it always matches against the id column. If your model's primary key isn't literally named id (e.g. prod_id), deleting through this endpoint won't work yet. Delete records with a non-id primary key directly through the console instead.

Response 200:

{ "success": true }

Errors

{ "error": "message" }
StatusMeaning
401Missing or invalid API key.
404Table or record not found.
429Rate limit exceeded.
500Unexpected server error.

Rate limits

Each API key is limited to 100 requests per minute, flat.

Exceeding it returns a 429 with an error message describing the limit.