Skip to main content

REST

The REST API endpoint is available inside the Depot environment VPC network. It is also exposed via the public API gateway endpoint for your environment.

A Network Load Balancer (NLB) is created with every Depot environment of type internal. This NLB's hostname is resolvable over the internet, however will always point to an internally accessible VPC endpoint IP address. Requests can be sent unencrypted when issued internally on port 80.

The NLB sits in front of the Depot Connector API.

You will only be able to access resources from this NLB from inside the VPC network. The Lambda Gateway function is preconfigured to send API requests to this internal endpoint when the function is invoked.

If you need custom integration, it is possible to use this endpoint, however you will need to supply the correct request headers.

Conventional rest endpoints

GET

GET https://{authkind}.{envid}.{accountid}.sdp.onstage.dev/{dataset}/{schema}/{id}

with authkind = iam (caller must operate within a role allowed to talk to the REST gateway, or public (Cognito-based)

With the following headers set:

  • X-Environment-Uri: points at the current environment state file
  • Authorization: Proxy {iamArn} (iam) or Bearer {token} (public)
  • X-Base-Domain: {dataset}
  • X-Domain: {dataset}

With the following query parameters optionally set:

  • expand: comma-separated list of names to expand

... TODO ...

Structured request endpoint (incl. batch requests)

All forms of request can be sent in a POST request to the dataset path of the REST API, suitably enveloped, for example:

POST https://public.{envid}.{accountid}.sdp.onstage.dev/{dataset}

or:

POST https://{dataset}.public.{envid}.{accountid}.sdp.onstage.dev

{
"update": {
"schema": "MySchema",
"id": "id1",
"data": {
...etc...
},
"mode": "merge",
...etc...
}
}

The following action types (set as wrapper keys) are supported:

  • read Supporting the following arguments:
    • schema (required) schema to read from
    • id (required) id to read
    • version (optional) version to read
    • expand (optional) set of names to expand
    • projection (optional)
    • consistency (optional)
    • linkConsistency (optional)
  • create
    • schema (required) schema to write to
    • data (required) property values
    • id (optional) id to read
    • expand (optional) set of names to expand in the response
    • projection (optional)
    • consistency (optional)
    • expressions (optional)
  • update
    • schema (required) schema to write to
    • data (required) property values
    • id (required) id to read
    • expand (optional) set of names to expand in the response
    • projection (optional)
    • consistency (optional)
    • expressions (optional)
  • delete
    • schema (required) schema to write to
    • id (required) id to delete
    • consistency (optional)
  • batch
    • actions (required) set of these actions, see below.

The consistency field

The optional consistency field on write actions (create, update, delete) controls the atomicity guarantee requested from the storage backend. Accepted values (strongest to weakest):

ValueMeaning
ATOMICFull cross-record atomicity — storage wraps the write in a transaction
QUORUMQuorum-based consistency
EVENTUALNo cross-record atomicity guarantee
ASYNCFire-and-forget

When omitted, the effective default depends on the dataset's location type:

Location typeDefaultStrongest acceptedTransactional SQL writes
Snowflake (native)ATOMICanyYes — BEGIN / COMMIT
Aurora (PostgreSQL)ATOMICanyYes — BEGIN / COMMIT
S3Tables (Snowflake Iceberg)ATOMICATOMIC (ATOMIC_ALL rejected)No — Iceberg provides single-table atomicity
DynamoDBQUORUMany

These structured requests can also be wrapped into a single batch request as follows:

{
"batch": {
"actions": {
"myAction1": {
"update": {
"schema": "MySchema",
"id": "id1",
"data": {
...etc...
},
"mode": "merge",
...etc...
}
},
"myAction2": {
"update": {
"schema": "MySchema",
"id": "id2",
"data": {
...etc...
},
"mode": "merge",
...etc...
}
}
}
}
}

The response from a batch request is a map with the response from each action keyed by the supplied name in the request, e.g.:

{
"myAction1": {
"id": "id1"
},
"myAction2": {
"id": "id2"
}
}

Dataset echo rest endpoints

An echo endpoint is provided for all Datasets in an environment, accessible by sending a GET request to the /echo path on the Dataset endpoint.

For example:

curl -H "Authorization: Bearer BEARER_TOKEN_HERE" https://public.{environment_id}.{aws_account_id}.sdp.onstage.dev/{dataset_id}/echo

{
"path" : "/",
"headers" : {
"empty" : false
},
"requestId" : "3186c0b1-c438-4dc1-bc04-014447469767",
"caller" : {
"anon" : false,
"schema" : "User",
"id" : "johnc",
"claims" : {
"sub" : "144fc6fc-c19d-4b95-ad2b-81d17ee12870",
"email_verified" : true,
"iss" : "https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_ZZZZZZZ",
"cognito:username" : "johnc",
"origin_jti" : "c2ba14f2-a8a4-42fa-a8f9-5159ad1003e4",
"aud" : [ "122qf84mf91flkvltal6zzzzz" ],
"event_id" : "d5a91697-719e-4030-b339-6f903b198021",
"token_use" : "id",
"auth_time" : 1664446348,
"exp" : 1664449948000,
"iat" : 1664446348000,
"jti" : "zzz2de0f-ae25-41b3-a417-f373a203364c",
"email" : "john@example.com"
},
"super" : false
},
"method" : "get",
"query" : {
"empty" : true
},
"contentType" : "json",
"accept" : "json"
}

The above endpoint can also be used to inspect the caller and claims provided by the authentication provider, in this case Cognito.

Raw SQL query endpoint

The raw SQL query endpoint allows you to execute arbitrary read-only SQL queries against the underlying database (Aurora/PostgreSQL or Snowflake) for a dataset. The connection is opened in read-only mode, so any DML (INSERT, UPDATE, DELETE) or DDL (DROP TABLE, etc.) statements will be rejected by the database.

Prerequisites

The endpoint is only available through the IAM gateway and must be explicitly enabled on the dataset configuration with rawSqlEndpointEnabled: true under auth.iam section in dataset config (see auth).

warning

If you're executing the Raw SQL query endpoint against a dataset in a Snowflake location you must make sure that the user provided in the executor config has the DEPOT_READONLY role assigned to it. Depot leverages this role to open a read only session and prevent DML/DDL operation from being run.

Endpoint URL

POST https://iam.{envid}.{accountid}.sdp.onstage.dev/{datasetId}/raw-query

Request body

The request body is a JSON object with the following properties:

PropertyTypeRequiredDescription
sqlstringYesThe SQL query string. May contain table/column replacement tokens (@{...}) and argument binding placeholders (${...}). Must not be blank.
usingmap<string, string>NoMaps short alias names used in @{...} tokens to fully-qualified schema names (e.g. "pet": "petstore.Pet"). Every alias referenced in the SQL must have a corresponding entry.
argumentsmap<string, Argument>NoNamed query parameters referenced by ${...} placeholders. Each entry is an Argument object (see below).

Argument object:

PropertyTypeRequiredDescription
valueanyYesThe value to bind.
typestringYesThe scalar type name.

Optional headers

The standard executor operation hint headers are supported on this endpoint, just as on any other REST API endpoint:

HeaderDescription
executor-nameOverride the default executor (e.g. a specific Snowflake warehouse).
tagsJSON-encoded tags to pass to the storage layer for observability, etc.

SQL replacement tokens

The sql string supports two kinds of replacement tokens that are resolved before the query is executed:

  • @{alias} — replaced with the fully qualified table name for the schema mapped to alias in the using map.
  • @{alias.property} — replaced with the physical column name for the given property in the schema mapped to alias. Nested paths are supported (e.g. @{p.store.id} resolves to the physical column for the store foreign-key id).
  • ${argName} — replaced with a parameterised bind variable whose value and type are taken from the matching entry in the arguments map. This is the recommended way to supply user-provided values safely.

For full details — naming strategies per backend, Iceberg quoting, history table aliases, cross-strategy views — see SQL tokens (@{} and ${}).

Example request

{
"sql": "SELECT p.name AS \"name\", s.name AS \"storeName\" FROM @{pet} p JOIN @{store} s ON p.store_id = s.id WHERE s.name = ${storeFilter}",
"using": {
"pet": "petstore.Pet",
"store": "petstore.Store"
},
"arguments": {
"storeFilter": {
"value": "MyStore",
"type": "string"
}
}
}

Response

The response is a JSON array of objects. Each object represents a row, with keys matching the column aliases defined in the SQL SELECT clause:

[
{
"name": "Fido",
"storeName": "MyStore"
},
{
"name": "Rex",
"storeName": "MyStore"
}
]

An empty result set returns [].

warning

Depot returns values returned by the DB server as-is. Therefore, if you want to ensure specific casing of field names (e.g. have them in lowerCase or PascalCase) ensure that column aliases are wrapped in double quotes. Otherwise, the DB engine will return them converted to the default naming convention (e.g. UPPER_CASE for Snowflake and snake_case for Aurora/Postgres).

Validation errors

HTTP StatusCondition
400sql is missing or blank.
400A @{...} token references an alias not declared in using.
400A ${...} placeholder references an argument name not present in arguments.
400An argument's type is not a recognised scalar type name (e.g. a typo or a non-string value such as 123).
403The request was sent through a non-IAM gateway (e.g. public).
403The raw SQL endpoint is not enabled for the target dataset.