Make your first DORIC API request
Make a verified, read-only List accounts request with provisioned sandbox access using TypeScript, cURL or Python.
- Audience
- Developer
- Owner
- DORIC developer experience
- Last reviewed
- Jul 20, 2026
- Reading time
- 8 min
On this page
Request at a glance
This tutorial makes one authenticated, read-only collection request. It does not create or modify banking data.
GET /accountsHTTP- Lists accounts owned by one customer or legal entity.
accounts.readOAuth 2.0 · Required- The access token must contain this permission.
ownerIdquery · Required- Identifies the customer or legal entity whose accounts you want to list.
200 OKHTTP- Returns an account collection and an optional continuation token.
Before you run the request
- You have the sandbox gateway and OAuth values assigned to your organization.
- You have a short-lived OAuth 2.0 access token containing the accounts.read scope.
- You have an ownerId from a sandbox customer or legal-entity record. It is not an account ID.
- You can use TypeScript with Bun or Node.js 20+, cURL 7.76+ with uuidgen, or Python 3 with httpx.
Make the request
- 01
Set the environment values
Replace the example owner ID and, when required, the preview base URL with values from your sandbox. Enter the token through a hidden prompt so the credential is not written into shell history.
bashexport DTCOM_BASE_URL="https://api.sandbox.dtcom.ai/v1" export DTCOM_OWNER_ID="customer_123" read -rsp "Sandbox access token: " DTCOM_ACCESS_TOKEN && echo export DTCOM_ACCESS_TOKEN - 02
Send the read-only request
Choose the sample that matches your application. Each version calls GET /accounts with the required ownerId, creates a unique request UUID and fails clearly when the response is not successful.
typescriptconst baseUrl = process.env.DTCOM_BASE_URL ?? "https://api.sandbox.dtcom.ai/v1"; const accessToken = process.env.DTCOM_ACCESS_TOKEN; const ownerId = process.env.DTCOM_OWNER_ID ?? "customer_123"; if (!accessToken) throw new Error("DTCOM_ACCESS_TOKEN is required"); const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl; const url = new URL(normalizedBaseUrl + "/accounts"); url.searchParams.set("ownerId", ownerId); const response = await fetch(url, { headers: { Accept: "application/json", Authorization: "Bearer " + accessToken, "X-Request-Id": crypto.randomUUID(), }, }); const payload = await response.json(); const requestId = response.headers.get("x-request-id"); if (!response.ok) { throw new Error( "DORIC request failed (" + response.status + "): " + JSON.stringify(payload), ); } console.log({ requestId, payload }); - 03
Confirm the status and trace identifier
A successful call returns HTTP 200 and an X-Request-Id response header. The gateway echoes the valid caller ID or generates one when the header is omitted. Preserve the returned value with logs and support evidence.
httpHTTP/2 200 content-type: application/json x-request-id: 5c09305d-f4cb-46e3-a8bf-f567f28b7c5d - 04
Read the account collection
Each account includes a stable ID, the requested owner ID, a three-letter currency, an integer minor-unit balance and a lifecycle status. The optional nextPageToken means another page is available.
json{ "accounts": [ { "id": "8d6907d9-f5db-47ed-a55d-f4a87e120d0c", "ownerId": "customer_123", "currency": "USD", "balanceMinor": 125000, "status": "active" } ], "nextPageToken": "eyJvZmZzZXQiOjUwfQ" }
Verify success
- The response uses HTTP 200.
- Every returned account belongs to the requested owner.
- Currency values use three-letter ISO 4217 codes.
- Balances are integers expressed in minor units.
- The response request ID can be correlated with your application logs.
- You continue with nextPageToken only when it is present and stop when it is omitted.
Open the source of truth
Use these routes to obtain access or inspect the deeper contract after completing the first request.
Advanced request handling
The first successful request is complete. Open this section when you are implementing collection traversal, validation or production-grade recovery.
Show request fields, pagination and failure recovery
Understand the request and response contract
Required values must be present exactly as documented. Tokens and identifiers are opaque: transmit them without parsing or changing them.
Authorizationheader · Required- Send the short-lived token as Bearer <token>. A token from another environment is not valid.
ownerIdquery · Required- Non-empty sandbox customer or legal-entity identifier. Do not substitute an account UUID.
pageSizeinteger · Optional- Optional maximum result count from 1 through 100. The contract default is 50.
pageTokenstring · Optional- Optional continuation token returned by a previous request. Send it unchanged with the same ownerId and pageSize.
X-Request-Idheader · UUID · Optional- Optional UUID unique to this HTTP request. The gateway echoes a valid supplied value or generates one, then returns it in the response header and structured errors.
accountsarray<Account> · Required- The accounts belonging to the requested owner. The array can be empty when the owner has no accounts.
nextPageTokenstring · Optional- Present only when another page is available. When omitted, pagination is complete.
Recognize a successful empty collection
{
"accounts": []
}Continue through every page
When nextPageToken is present, send its value as pageToken in the next request. Keep ownerId, pageSize and every other query parameter identical to the request that produced the token.
Treat pagination tokens as opaque values. Do not decode them, build your own token or assume their internal format. Stop when nextPageToken is omitted from the response.
Request the next page
DTCOM_REQUEST_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')"
curl --silent --show-error --get \
--url "$DTCOM_BASE_URL/accounts" \
--data-urlencode "ownerId=$DTCOM_OWNER_ID" \
--data-urlencode "pageSize=50" \
--data-urlencode "pageToken=eyJvZmZzZXQiOjUwfQ" \
--header "Authorization: Bearer $DTCOM_ACCESS_TOKEN" \
--header "Accept: application/json" \
--header "X-Request-Id: $DTCOM_REQUEST_ID"Resolve errors without guessing
Read the HTTP status, the structured error body and its requestId together. Preserve the requestId before changing or retrying the request.
400 INVALID_ARGUMENTHTTP- Correct the request before retrying. Check that ownerId is non-empty, pageSize is between 1 and 100, and pageToken is unchanged.
401 UNAUTHENTICATEDHTTP- Obtain a new token for this sandbox. Confirm that the Authorization header uses Bearer and that the token has not expired.
403 PERMISSION_DENIEDHTTP- Confirm that the token contains accounts.read and that sandbox policy permits access to this owner's records.
429 RESOURCE_EXHAUSTEDHTTP- Stop sending requests, honor Retry-After, then retry with exponential backoff and jitter.
503 UNAVAILABLEHTTP- The service is temporarily unavailable. Honor Retry-After and retry this unchanged GET request with exponential backoff and jitter.
Read a structured rate-limit error
HTTP/2 429
content-type: application/json
retry-after: 2
x-request-id: 6214a2de-c932-4b2e-b55c-1f31d5e9a0c7
{
"error": {
"code": "RESOURCE_EXHAUSTED",
"message": "Request rate limit exceeded.",
"requestId": "6214a2de-c932-4b2e-b55c-1f31d5e9a0c7",
"details": []
}
}Continue learning