Introduction to GraphQL

21 Travel Rule exposes its business logic through a single GraphQL schema. The same API powers the Compliance Dashboard and your own integrations.

Endpoints and transports

  • HTTP requests are sent to /graphql using POST with a JSON body containing a query string and optional variables.
  • Subscriptions use the WebSocket endpoint /graphql-ws, following the graphql-ws protocol. Both use the same schema and authentication model.
  • Authentication is required for all operations; use a Keycloak-issued bearer token as described in Authentication.

Example HTTP call:

curl -X POST https://yourvasp.intranet/graphql \
  -H "Authorization: Bearer <access-token>" \
  -H "Content-Type: application/json" \
  --data '{"query":"query { trpd { vasps { name } } }"}'

How the schema is structured

  • Root fields – The schema is namespaced by domain: trpd covers Travel Rule Protocol operations, aopd covers address-ownership proofs, and autod exposes administrative data used by the Compliance Dashboard.
  • Queries fetch data (for example trpd { vasps { name } }).
  • Mutations perform actions (for example trpd { inquire(...) } to start a TRP flow or trpd { confirmTx(...) } to submit a transaction hash).
  • Subscriptions stream updates (trpdTransactions and aopdProofs are the primary channels).

GraphQL validates every request against the schema, so you only receive fields that exist and match the declared types.

Arguments, variables, and selection sets

  • Arguments are passed directly to fields: trpd { validateTravelAddress(input: "...") }.

  • Use variables to keep queries reusable:

    {
        "query": "query Check($address: String!) { trpd { validateTravelAddress(input: $address) } }",
        "variables": { "address": "taEJKtAQyrS5x6i59GBS2fcbbZDB9VM9r4yKeWR" }
    }
    
  • Selection sets let you choose only the fields you need, which keeps responses small and stable even as the schema grows.

Discoverability and errors

  • The API is fully introspectable. You can use GraphiQL to interactively explore the full API.
  • GraphQL responses always return an errors array alongside data. When a mutation fails validation or business rules, expect errors[0].message to contain the reason, while data is set to null for the failing field.