REST API
A data source's tables, from another application, with a key. Everything below is
also in /api/v1/openapi.json, generated from the live schema.
On this page
A key #
Make one under the project's settings, in API keys. It is shown once and
stored as a hash. The key says which project; every request names the data source
with ?source=, and one that names none is refused with the names the
project has. A project's id never appears in an address.
A key is read and write, or read only (GET, HEAD, OPTIONS), and may be narrowed to some tables of the source it was made
on. It acts for the person who made it: taken out of the project, they take its
access with them. Writes made with a key are listed in the project's Activity.
curl -H "Authorization: Bearer 10lines_XXXX" \
"https://10lines.io/api/v1/tables/orders?source=shop&per_page=50&order_by=-total&status[eq]=paid"
What there is #
| Request | Does |
|---|---|
GET /api/v1/schema |
tables, columns, relationships and saved views |
GET /api/v1/openapi.json |
the same as an OpenAPI 3.1 document, only the tables the key reaches |
GET /api/v1/tables/:table |
rows |
GET /api/v1/tables/:table/:id |
one row |
POST /api/v1/tables/:table |
a new row |
PUT, PATCH /api/v1/tables/:table/:id |
a change to a row |
DELETE /api/v1/tables/:table/:id |
a row gone |
POST, PATCH, DELETE /api/v1/tables/:table/bulk
|
many rows at once, all or nothing |
GET /api/v1/tables/:table/export.csv, export.json |
the whole table, streamed |
/api/v1/tables/:table/:id/links/:relationship |
many-to-many links: GET lists them, PUT replaces the
set, POST adds, DELETE removes
|
Listing rows #
| Option | Example | Means |
|---|---|---|
page, per_page |
?per_page=50 |
page by number; at most 200 a page |
fields |
?fields=id,code |
only these columns |
order_by |
?order_by=code,-total |
by several columns; - is descending |
q |
?q=ada |
the text columns contain it; a whole number is also looked for in the number columns |
| filters | ?total[gt]=10 |
eq, ne, gt, gte, lt, lte,
in
(comma-separated), contains, starts_with, ends_with,
null
(true
or false); ?total=10
is eq
|
view |
?view=3 |
a saved view; anything else given narrows it further |
cursor |
?cursor= |
walk a big table, below |
A page answers data
and, under meta, page, per_page, total
and total_pages. A read has
five seconds; when counting the rows takes longer, the page still comes back,
total_exact
is false
and total
is what is
certain.
A big table #
Paging by number makes the database count past every row it skips. A cursor costs
the same wherever it lands: start with an empty ?cursor=
and a single order_by
column, and follow next_cursor
until it is null. It does not count the table, so there is no total.
GET /api/v1/tables/orders?source=shop&order_by=id&cursor=
→ {"data": [...], "meta": {"per_page": 25, "next_cursor": "g2gCYQFhAg"}}
GET /api/v1/tables/orders?source=shop&order_by=id&cursor=g2gCYQFhAg
→ {"data": [...], "meta": {"per_page": 25, "next_cursor": null}}
Writing #
A row's values go under data. They are cast and checked against the
column's type and its field settings before anything is written, and a refusal is
a 422 with an errors map by column.
curl -X POST -H "Authorization: Bearer 10lines_XXXX" \
-H "Content-Type: application/json" \
-d '{"data": {"code": "A-1001", "total": 42}}' \
"https://10lines.io/api/v1/tables/orders?source=shop"
A bulk call carries data as a list (each with an id for an
update) or ids for a delete, up to 1000 rows. It is all or nothing, and a
refusal names the position or id of every row that failed.
curl -X POST -H "Authorization: Bearer 10lines_XXXX" \
-H "Content-Type: application/json" \
-d '{"data": [{"code": "A-1"}, {"code": "A-2"}]}' \
"https://10lines.io/api/v1/tables/orders/bulk?source=shop"
curl -X DELETE -H "Authorization: Bearer 10lines_XXXX" \
-H "Content-Type: application/json" \
-d '{"ids": [1, 2]}' \
"https://10lines.io/api/v1/tables/orders/bulk?source=shop"
Caching and browsers #
Reads carry an ETag; send it back as If-None-Match and an
unchanged answer is a 304 with no body. CORS headers are sent, from
any origin unless the server is told otherwise: requests authenticate with a key in
a header, not a cookie.
Limits and errors #
| Status | When |
|---|---|
401 |
no key, or not one this server issued |
403 |
a write with a read-only key, a table the key does not reach, or a missing or
unknown ?source=
|
404 |
no such table or row |
409 |
a unique column already has that value |
422 |
values that do not fit, with errors by column |
429 |
over the key's limit; every answer carries x-ratelimit-limit,
x-ratelimit-remaining
and x-ratelimit-reset, and this
one retry-after
|