Skip to main content
Effective date: 2026-05-20. Use this guide when updating code that reads agreement records or input history from the Agreements API or @cns-labs/agreements-api-client.

What changed

Authenticated agreement routes return response envelopes. Raw single-resource HTTP responses use data and meta; raw list responses use data, pageInfo, and meta.
Route typeRaw HTTP success shape
Single-resource routes{ "data": ..., "meta": { "apiVersion": "v0", "requestId": "..." } }
List routes{ "data": [...], "pageInfo": { "limit": 25, "nextCursor": "..." }, "meta": { "apiVersion": "v0", "requestId": "..." } }
Health checkUnchanged: { "status": "ok", "service": "external-api", "timestamp": "..." }
The TypeScript client unwraps single-resource methods such as getAgreement(...), validateTemplate(...), validateDeployment(...), deployWithPermit(...), getAgreementState(...), and submitAgreementInput(...). List methods return the list envelope so callers can read data, pageInfo, and meta.

Upgrade checklist

  1. Upgrade to @cns-labs/agreements-api-client 0.2.0 or newer. This is the minimum version for the response-envelope changes described here.
  2. Update raw HTTP consumers to read resource responses from response.data.
  3. Update list consumers to iterate over response.data.
  4. Use response.pageInfo.nextCursor for the next page when present.
  5. Store or log response.meta.requestId when support traceability matters.
  6. Update error handling to read error.code, error.message, optional error.details, and error.requestId.

SDK before and after

Before 0.2.0, list methods returned arrays:
const agreements = await client.listAgreements();
console.log(agreements[0].id);

const inputs = await client.listAgreementInputs(agreementId);
console.log(inputs.length);
In 0.2.0, list methods return paged envelopes:
const agreementsPage = await client.listAgreements({ limit: 25 });
console.log(agreementsPage.data[0]?.id);
console.log(agreementsPage.pageInfo.nextCursor);

const inputsPage = await client.listAgreementInputs(agreementId, { limit: 25 });
console.log(inputsPage.data.length);
Single-resource SDK methods continue to return the resource directly:
const agreement = await client.getAgreement(agreementId);
const state = await client.getAgreementState(agreementId);
Agreement list items are summaries. Use getAgreement(id) when you need full agreement JSON, participants, observers, variables, or on-chain context.

Query parameters

Agreement lists support limit, cursor, state, createdAt, updatedAt, and one sort field from createdAt, updatedAt, or displayName. Input history lists support limit, cursor, userId, inputId, status, createdAt, updatedAt, and one sort field from createdAt or updatedAt. Date filters use bracket operators:
curl --globoff -sS "$BASE_URL/v0/agreements?createdAt[gte]=2026-05-01T00:00:00.000Z&sort[createdAt]=desc&limit=25" \
  -H "X-API-Key: $API_KEY"
Use --globoff with curl when sending bracket query parameters.

Error responses

Errors use a top-level error object:
{
  "error": {
    "code": "bad_request",
    "message": "Unsupported query parameter \"foo\"",
    "requestId": "req_123"
  }
}
Branch on error.code and include error.requestId when reporting a failure.