AAkilIQ
Get an API key

Reference

API reference

Read published datasets with an API key.

OpenAPI document

This page is rendered from the OpenAPI 3.1 document, which is generated from the data API's implementation.

Download the OpenAPI document

Read a page of a published dataset's rows.

GET/v1/datasets/{dataset_id}/rows

The Query Specification travels as JSON in the q parameter; a request with a matching If-None-Match is answered 304.

API key operationrows

Parameters

NameInRequiredDescription
dataset_idpathYesThe published dataset's ID.
If-None-MatchheaderNoThe ETag of a page already held.
qqueryNoThe Query Specification as JSON; absent, the first page of every returnable field.

Responses

StatusAnswerHeaders
200A page of rows.ETagX-Correlation-IDX-Credits-ConsumedX-Quota-Limit?X-Quota-Period?X-Quota-Remaining?X-Quota-Reset?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
304The page is unchanged since the ETag sent; a tenth of the credits.ETagX-Correlation-IDX-Credits-ConsumedX-Quota-Limit?X-Quota-Period?X-Quota-Remaining?X-Quota-Reset?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
400query_invalidquery_malformedX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
401unauthenticatedWWW-AuthenticateX-Correlation-ID
403operation_not_permittedX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
404not_foundX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
413query_malformedX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
429rate_limitedquota_exceededRetry-AfterX-Correlation-IDX-Credits-Consumed?X-Quota-Limit?X-Quota-Period?X-Quota-Remaining?X-Quota-Reset?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
500internal_errorX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
503unavailablerate_limit_unavailablemetering_unavailableRetry-After?X-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
504query_timeoutX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?

A header marked with a question mark is sent only when it applies.

Query a published dataset with the specification in the request body.

POST/v1/datasets/{dataset_id}/query

For a specification too long for a URL; it answers exactly as the rows endpoint does.

API key operationquery

Parameters

NameInRequiredDescription
dataset_idpathYesThe published dataset's ID.
If-None-MatchheaderNoThe ETag of a page already held.
bodyapplication/jsonYesThe Query Specification, at most 64 KiB.

Responses

StatusAnswerHeaders
200A page of rows.ETagX-Correlation-IDX-Credits-ConsumedX-Quota-Limit?X-Quota-Period?X-Quota-Remaining?X-Quota-Reset?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
400query_invalidquery_malformedX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
401unauthenticatedWWW-AuthenticateX-Correlation-ID
403operation_not_permittedX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
404not_foundX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
412precondition_failedX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
413query_malformedX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
429rate_limitedquota_exceededRetry-AfterX-Correlation-IDX-Credits-Consumed?X-Quota-Limit?X-Quota-Period?X-Quota-Remaining?X-Quota-Reset?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
500internal_errorX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
503unavailablerate_limit_unavailablemetering_unavailableRetry-After?X-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?
504query_timeoutX-Correlation-IDX-Credits-Consumed?X-RateLimit-Limit?X-RateLimit-Remaining?X-RateLimit-Reset?X-Request-ID?

A header marked with a question mark is sent only when it applies.

Error codes

Every error has the same shape: a stable code, a message, the correlation ID, and details where there is something to act on.

CodeStatusMeaning
query_invalid400The dataset's descriptor refuses the query; details.rejections lists every reason.
query_malformed400, 413The Query Specification cannot be read: not a JSON object, another query parameter, or larger than 64 KiB.
unauthenticated401No API key, or one that is unknown, revoked, expired or of a deactivated organisation.
operation_not_permitted403The API key is not scoped to this operation.
not_found404No such dataset, not published, or outside the key's datasets: one answer for all three.
method_not_allowed405The resource does not answer that method.
precondition_failed412A POST whose If-None-Match matched the current representation.
rate_limited429The key's or the organisation's burst is spent; retry after Retry-After seconds.
quota_exceeded429The request would pass the period's credit quota; details say which quota and where to get more.
internal_error500Something failed on our side; quote the correlation ID.
unavailable503A dependency is out of reach or the dataset is being republished; try again shortly.
rate_limit_unavailable503Rate limiting cannot be consulted and this deployment refuses what it cannot limit.
metering_unavailable503Usage cannot be recorded, and nothing is served unrecorded; try again shortly.
query_timeout504The query ran longer than the service allows; narrow the filter or page with the cursor.

Response headers

HeaderMeaning
DeprecationWhen this operation was deprecated, as @ and Unix seconds.
ETagThe page's strong entity tag; send it back in If-None-Match.
LinkWhere the deprecation notice is published.
Retry-AfterSeconds to wait before the next request would be served.
SunsetThe first day this operation may no longer be served.
WWW-AuthenticateThe authentication scheme the data API expects.
X-Correlation-IDThe correlation ID of this request; quote it when reporting a problem.
X-Credits-ConsumedThe credits this request consumed, by the published formula.
X-Quota-LimitThe credits of the binding quota for the period.
X-Quota-PeriodThe quota period: hour, day or month.
X-Quota-RemainingThe credits of that quota left after this request.
X-Quota-ResetSeconds until the quota period ends.
X-RateLimit-LimitThe burst of the rate-limit bucket that binds this request.
X-RateLimit-RemainingRequests left in that bucket after this one.
X-RateLimit-ResetSeconds until that bucket is full again.
X-Request-IDThe ID this request's metering event is recorded under.

Schemas

Page
{
  "additionalProperties": false,
  "description": "One page of results (FR-API-003, FR-API-025).\n\n`credits_consumed` is on every response, not only on a quota error. Opaque consumption destroys developer trust faster than a restrictive limit does, so the cost of a call is reported at the moment the call is made.",
  "properties": {
    "credits_consumed": {
      "minimum": 0,
      "type": "number"
    },
    "data": {
      "items": {
        "type": "object"
      },
      "type": "array"
    },
    "dataset_version": {
      "description": "The version actually read, so a dynamic subset's staleness is visible.",
      "type": [
        "string",
        "null"
      ]
    },
    "next_cursor": {
      "description": "Absent when this is the last page. Opaque.",
      "type": [
        "string",
        "null"
      ]
    },
    "total": {
      "description": "Absent unless the caller asked for it: an exact count is a second scan, and most callers do not need one.",
      "minimum": 0,
      "type": [
        "integer",
        "null"
      ]
    }
  },
  "required": [
    "data",
    "credits_consumed"
  ],
  "title": "Page",
  "type": "object"
}
Error
{
  "additionalProperties": false,
  "description": "The one error shape every AkilIQ surface returns.\n\n`code` is stable and machine-readable, never a bare string, so an integrator can branch on it without parsing prose. `correlation_id` is present on every error, so a user reporting a problem quotes something that maps to a trace (NFR-OBS-003, FR-ADM-006).\n\nNo error message carries a secret, a DSN, a stack trace or a database identifier.",
  "properties": {
    "code": {
      "examples": [
        "quota_exceeded",
        "rate_limited",
        "field_not_filterable",
        "not_found"
      ],
      "pattern": "^[a-z][a-z0-9_]*$",
      "type": "string"
    },
    "correlation_id": {
      "pattern": "^cor_[0-9a-f]{32}$",
      "type": "string"
    },
    "details": {
      "description": "Structured specifics — which field, which operator, which limit — so a client can act without parsing the message.",
      "type": "object"
    },
    "documentation_url": {
      "format": "uri",
      "type": "string"
    },
    "message": {
      "description": "Human-readable, and safe to show a caller.",
      "minLength": 1,
      "type": "string"
    }
  },
  "required": [
    "code",
    "message",
    "correlation_id"
  ],
  "title": "Error",
  "type": "object"
}
Rejection
{
  "additionalProperties": false,
  "properties": {
    "code": {
      "enum": [
        "unknown_field",
        "field_not_returnable",
        "field_not_filterable",
        "field_not_sortable",
        "field_not_searchable",
        "operator_not_permitted",
        "value_required",
        "value_not_permitted",
        "value_must_be_list",
        "value_must_not_be_list",
        "limit_exceeded",
        "search_not_supported",
        "dataset_mismatch",
        "value_type_mismatch",
        "limit_invalid",
        "offset_invalid",
        "offset_exceeded",
        "pagination_conflict",
        "cursor_invalid",
        "sort_direction_invalid",
        "cost_exceeded"
      ],
      "type": "string"
    },
    "field": {
      "type": "string"
    },
    "message": {
      "type": "string"
    }
  },
  "required": [
    "code",
    "message"
  ],
  "type": "object"
}
QuerySpecification
{
  "additionalProperties": false,
  "description": "The one internal representation every read surface compiles to (FR-API-001).\n\nREST today, GraphQL later, internal consumers throughout — all of them produce this. Authorisation, field permissions and limits are applied once, to this specification, never per surface. That is what makes a second surface additive rather than a second place to get permissions wrong.",
  "properties": {
    "cursor": {
      "description": "An opaque continuation token (FR-API-003). Opaque on purpose: a caller that can construct one can page outside the ordering the descriptor guarantees.\n\nWithin the specification it is the unpadded base64url encoding of `{\"after\": [...], \"order\": [[field, direction], ...]}` — the key values of the last row returned, and the order they were read in. A surface that hands cursors to callers seals that payload and opens it before building a specification.",
      "type": "string"
    },
    "dataset": {
      "description": "May be left out: the path names the dataset. If given, it must be the path's.",
      "pattern": "^ds_[0-9A-HJKMNP-TV-Z]{26}$",
      "type": "string"
    },
    "filters": {
      "items": {
        "$ref": "#/components/schemas/QuerySpecificationFilter"
      },
      "type": "array"
    },
    "limit": {
      "minimum": 1,
      "type": "integer"
    },
    "offset": {
      "description": "Offset pagination (FR-API-003). Available but capped, because deep offsets scan what they skip.",
      "minimum": 0,
      "type": "integer"
    },
    "search": {
      "additionalProperties": false,
      "properties": {
        "fields": {
          "items": {
            "$ref": "#/components/schemas/QuerySpecificationIdentifier"
          },
          "type": "array",
          "uniqueItems": true
        },
        "query": {
          "maxLength": 512,
          "minLength": 1,
          "type": "string"
        }
      },
      "required": [
        "query"
      ],
      "type": "object"
    },
    "select": {
      "description": "Field projection (FR-API-004). Intersected against the descriptor's returnable set; omitted means every returnable field.",
      "items": {
        "$ref": "#/components/schemas/QuerySpecificationIdentifier"
      },
      "type": "array",
      "uniqueItems": true
    },
    "sort": {
      "description": "Sorting, on publisher-permitted fields only (FR-API-005).",
      "items": {
        "$ref": "#/components/schemas/QuerySpecificationSort"
      },
      "type": "array"
    },
    "version": {
      "default": "latest",
      "description": "A dataset version, or `latest`. A dynamic subset resolves this at read time and reports what it resolved against, so staleness is never ambiguous (FR-FLOW-013).",
      "type": "string"
    }
  },
  "title": "Query Specification",
  "type": "object"
}