c.l.cladDocs

How the API works

GraphQL in practice: one POST, selection sets, variables, and reading the response — for developers new to GraphQL.

If you've used REST but not GraphQL, this is everything you need to be productive. You don't need to learn GraphQL in depth first — the format below covers the vast majority of real usage.

It's one POST request

There are no per-resource URLs like GET /issues/123. Every call — reading or writing — is an HTTP POST to the single /graphql endpoint with a JSON body containing two things:

{
  "query": "…the operation you want to run…",
  "variables": { "…values the operation uses…": "…" }
}

That's the whole transport. If you can send a JSON POST with a header, you can call this API in any language — no GraphQL client library required.

Reading the query string

The query field holds a GraphQL operation. It starts with a keyword:

  • query { … } — read data (like a GET).
  • mutation { … } — change data (like POST/PATCH/DELETE).

Inside the braces you name the operation you want, then — and this is the part REST doesn't have — you list exactly which fields you want back. The server returns those fields and nothing else, so you never over- or under-fetch:

query {
  issue(id: "SXNzdWU6MTAyNA==") {
    ticketNumber        # ← ask for the fields you want
    subject
    status
  }
}

If you leave a field out, it isn't returned. If you ask for a field that has its own sub-fields (a nested object), you open another { … } and list those too:

query {
  issue(id: "SXNzdWU6MTAyNA==") {
    subject
    messages(first: 5) {          # a connection…
      edges { node { body } }     # …so drill in for the fields you want
    }
  }
}

The Reference section lists every operation, its arguments, and the type it returns — so you always know which fields are available to request.

Use variables, not string interpolation

Don't paste values into the query string. Declare them with a $name and pass them in the separate variables object. This is safer (no injection, correct typing) and is how every example in these docs is written:

{
  "query": "mutation Create($input: CreateIssueInput!) { createIssue(input: $input) { issue { id ticketNumber } error { code message } } }",
  "variables": {
    "input": { "subject": "Login broken", "requesterEmail": "jane@example.com" }
  }
}

The $input: CreateIssueInput! part declares a variable named input of type CreateIssueInput (the ! means required). The matching value lives in variables. Every input type is documented in the Reference.

Reading the response

The response mirrors your query. Successful data comes back under data, keyed by the operation and shaped like the fields you asked for:

{ "data": { "issue": { "ticketNumber": 1024, "subject": "Login broken", "status": "open" } } }

Two kinds of failure can appear:

  • Transport / query errors (bad syntax, unknown field, missing auth) come back in a top-level errors array — often with data: null.
  • Business errors (validation, not-found, forbidden) come back as an error object inside the mutation payload, so data is still present. This is why most mutations here select an error { code message } field. See Errors for the full taxonomy.

Try it without writing code

Open the endpoint in a browser to get the API Explorer (a GraphiQL IDE) with live schema docs, autocomplete, and a run button — the fastest way to learn the shape of an operation before you wire it into code.

Open the API Explorer →

Want the language itself? This page covers everything you need for Clad. To go deeper on GraphQL as a language, see the official intro at graphql.org/learn.