# How the API works

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

Product: Clad API
Source: https://docs.useclad.ai/api/how-the-api-works

---

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:

```json
{
  "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:

```graphql
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:

```graphql
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:

```json
{
  "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](#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:

```json
{ "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](#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 →](https://clad-server-production.up.railway.app/graphql)**

> **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](https://graphql.org/learn/).
