REST API
Predictable resource endpoints. Every dataset exposes the same shape, so once you learn one you know them all.
Core Endpoints
Every dataset exposes the same predictable resource shape.
| Method | Endpoint | Description |
|---|---|---|
| GET | /v1/:dataset/:table | Page through records from a table you are subscribed to |
Tables in This Dataset
The first live dataset is vendor-master-data-general-us. Its table paths use hyphens where the underlying table names use underscores, so the columns of vendor_contacts are read at vendor-contacts. Every child table carries a vendor_id that joins back to vendors.
| Endpoint | Rows |
|---|---|
/v1/vendor-master-data-general-us/vendors | 10,000 |
/v1/vendor-master-data-general-us/vendor-contacts | 23,087 |
/v1/vendor-master-data-general-us/vendor-addresses | 20,845 |
/v1/vendor-master-data-general-us/vendor-bank-accounts | 11,183 |
/v1/vendor-master-data-general-us/vendor-categories | 21,126 |
/v1/vendor-master-data-general-us/vendor-certifications | 18,668 |
/v1/vendor-master-data-general-us/vendor-company-codes | 11,174 |
/v1/vendor-master-data-general-us/vendor-purchasing-orgs | 11,495 |
Example Request
Authenticate with your key, then narrow the response with select and a filter:
curl -sS https://www.datlyne.com/v1/vendor-master-data-general-us/vendors \
-H "Authorization: Bearer dtl_live_ab3k9x_••••••••" \
-G --data-urlencode "select=vendor_id,vendor_name,city,spend_ytd" \
--data-urlencode "vendor_status=eq:active" \
--data-urlencode "limit=100"Query Parameters
Four querystring keys are reserved. Every other key is read as a filter on a column of the same name.
| Parameter | Description |
|---|---|
select | Comma separated list of columns to return. Unknown names are rejected with 400. Defaults to every column. |
sort | Order by one sortable column, ascending. There is no descending option, and ties are broken by the key columns. |
limit | Records per page. Defaults to 100 and is capped at your plan maximum. |
cursor | The next_cursor from the previous page. Keyset based, so pages never shift or repeat. |
Filtering
Filter any filterable column with ?column=operator:value. Repeat a column to AND multiple conditions, for example ?spend_ytd=gt:100000&spend_ytd=lt:500000.
The operator is never optional. A bare ?country_code=US is rejected with 400 unknown_filter rather than being read as equality. Write ?country_code=eq:US. That way a mistyped filter fails loudly instead of silently widening your query.
| Operator | Description |
|---|---|
eq | Equal to the value |
gt | Greater than the value |
lt | Less than the value |
gte | Greater than or equal to the value |
lte | Less than or equal to the value |
like | SQL LIKE pattern match, string columns only |
in | Matches any value in a comma separated list, for example in:manufacturer,distributor |
Pagination
List endpoints return a page of records plus a next_cursor and a has_more flag. Pass the cursor back as the cursor parameter to fetch the next page, and stop once has_more is false. Page sizes default to 100 records and cap at your plan's max rows per response. The cursor is built from the table's key columns internally, so select never has to include them. Test has_more rather than checking whether next_cursor is null. It is the explicit signal that another page exists.
Error Codes
The API uses standard HTTP status codes. Error bodies also carry a machine readable error code you can branch on.
| Status | Meaning | Description |
|---|---|---|
400 | Bad Request | Malformed select, sort, filter, limit, or cursor parameter (error: unknown_field, unknown_sort, unknown_filter, invalid_limit, or invalid_cursor) |
401 | Unauthorized | Missing, malformed, or revoked API key (error: invalid_key) |
403 | Forbidden | Key does not cover this dataset, or the entitlement behind it has expired (error: scope_denied or entitlement_expired) |
404 | Not Found | Unknown dataset or table. Checked before any scope check, so a bad slug never leaks through as a 403 (error: unknown_dataset or unknown_table) |
429 | Too Many Requests | Rate or daily row quota exceeded. Back off for the seconds named in Retry-After (error: rate_limited or quota_exceeded) |
500 | Server Error | Something failed on our side, so retry with backoff (error: internal_error) |
503 | Service Unavailable | The read pool was momentarily saturated, so the request was shed instead of queued. Retry after the seconds named in Retry-After (error: server_busy) |
Prefer to select exact fields, or read related tables in one request? The GraphQL API will do that. It is planned but not yet available.