AT Agent Tables
Operational API

Build against operational tables with scoped tokens and bounded SQL.

Create schemas in the owner UI, issue read or write tokens, ingest JSON rows, and let agents query only through a guarded API surface.

Base URL
https://agent-tables.presleycobb.com/api
Auth
Bearer token
Default limit
25 rows
Maximum limit
100 rows

Quickstart

From empty account to first API call

The API reads and writes tables that owners define in the application. A typical integration starts in the UI, then moves to your service or agent runtime once a scoped token exists.

1

Create a table

Define table name, description, column types, required fields, enum values, and hidden fields.

2

Issue a token

Use the API tokens screen to create a token with read, write, or both abilities.

3

Call the API

Send JSON row writes from systems, or let agents run bounded read queries through /api/query.

Authentication

Use bearer tokens with explicit abilities

Every API request must include a bearer token. Table metadata and query execution require read; row ingestion requires write.

Ability Allows Typical actor
read List table metadata, inspect one table, run controlled read SQL. Agent runtime
write Insert JSON rows into a table. Source system or sync job

Schema model

Tables expose documented columns, not database internals

Metadata responses include system columns and visible user-defined columns. Hidden columns can still be accepted during writes when they exist in the schema, but they are omitted from public metadata by default.

Supported types

id string text enum boolean number datetime json

Built-in system columns

id
Auto-incrementing row identifier assigned by the data plane.
created_at
UTC timestamp recorded when the row is inserted.

Endpoints

The complete API surface

All endpoints live under https://agent-tables.presleycobb.com/api. The examples below use a support tickets table because it exercises required fields, enum values, booleans, datetime fields, JSON, and hidden metadata.

GET

/api/tables

read

Returns metadata for every table available to the token owner.

Request

curl https://agent-tables.presleycobb.com/api/tables \
  -H "Authorization: Bearer $READ_TOKEN" \
  -H "Accept: application/json"

Response

{
  "tables": [
    {
      "table": "tickets",
      "description": "Support tickets available to agents.",
      "columns": [
        {
          "name": "id",
          "type": "id",
          "description": "Auto-incrementing row identifier assigned by the data plane.",
          "required": true,
          "hidden": false,
          "system": true
        },
        {
          "name": "created_at",
          "type": "datetime",
          "description": "UTC timestamp recorded when the row is inserted.",
          "required": true,
          "hidden": false,
          "system": true
        },
        {
          "name": "external_id",
          "type": "id",
          "description": "Stable ticket identifier from the source system.",
          "required": true,
          "hidden": false,
          "system": false
        },
        {
          "name": "status",
          "type": "enum",
          "description": "Current lifecycle status of the ticket.",
          "values": ["open", "closed"],
          "required": true,
          "hidden": false,
          "system": false
        },
        {
          "name": "urgent",
          "type": "boolean",
          "description": "Whether the ticket requires immediate attention.",
          "required": true,
          "hidden": false,
          "system": false
        }
      ]
    }
  ]
}
GET

/api/tables/{table}

read

Returns one table metadata document, scoped to the authenticated token owner.

Request

curl https://agent-tables.presleycobb.com/api/tables/tickets \
  -H "Authorization: Bearer $READ_TOKEN" \
  -H "Accept: application/json"

Response

{
  "table": "tickets",
  "description": "Support tickets available to agents.",
  "columns": [
    {
      "name": "id",
      "type": "id",
      "description": "Auto-incrementing row identifier assigned by the data plane.",
      "required": true,
      "hidden": false,
      "system": true
    },
    {
      "name": "status",
      "type": "enum",
      "description": "Current lifecycle status of the ticket.",
      "values": ["open", "closed"],
      "required": true,
      "hidden": false,
      "system": false
    }
  ]
}
POST

/api/tables/{table}/rows

write

Inserts one JSON row into the addressed table. The request body is the row itself, not an envelope.

Request

curl https://agent-tables.presleycobb.com/api/tables/tickets/rows \
  -X POST \
  -H "Authorization: Bearer $WRITE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "TCK-001",
    "status": "open",
    "urgent": true,
    "opened_at": "2026-05-09T14:30:00Z",
    "metadata": {
      "source": "zendesk"
    }
  }'

Success response

A valid insert returns 204 No Content. Invalid rows return field-level details, including missing required fields, type errors, invalid datetimes, or unknown fields.

POST

/api/query

read

Runs a bounded read query. Use positional parameters with ? or named parameters with :name.

Request

curl https://agent-tables.presleycobb.com/api/query \
  -X POST \
  -H "Authorization: Bearer $READ_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sql": "select external_id, status from tickets where status = :status order by id",
    "params": {
      "status": "open"
    },
    "limit": 10
  }'

Response

{
  "columns": ["external_id", "status"],
  "rows": [
    {
      "external_id": "TCK-001",
      "status": "open"
    }
  ],
  "row_count": 1,
  "limit": 10,
  "has_more": false
}

Query rules

Read queries are wrapped and guarded

Query execution is intentionally constrained so agents can inspect operational data without receiving direct database credentials.

Accepted

  • Statements beginning with select or non-recursive with.
  • Scalar positional or named parameters.
  • Omitted limits default to 25; values above 100 are capped.
  • rows_only: true when an array response is easier for an agent.

Rejected

  • Semicolons or non-read statements.
  • Recursive common table expressions.
  • SQLite metadata and internal table references.
  • High-cost or filesystem functions such as randomblob and load_extension.

Errors

Every API error has the same envelope

Clients can branch on the stable error code, show the human-readable message, and inspect details for field errors or rejection reasons.

Validation example

{
  "error": "validation_failed",
  "message": "The row was invalid.",
  "details": {
    "fields": {
      "unknown_field": ["The field is not defined by the table schema."],
      "status": ["The field is required."],
      "urgent": ["The field must be a boolean."],
      "opened_at": ["The field must be a UTC ISO datetime string."]
    }
  }
}

Common statuses

401
Missing or invalid token.
403
Token lacks the required ability.
422
Validation or query rejection.
404
Requested table was not found.
409
Account setup is not ready for API access.
429
Rate limit exceeded; check Retry-After.