# GraphQL

One endpoint for reads and writes across areas, with the same keys and scopes as REST.

## Endpoint

Send queries and mutations to `POST https://api.rivier.ai/graphql` with the same key as REST. A field needs the same scope as the operation behind it; a field the key may not use answers an error with the code `FORBIDDEN` and the scope required.

Request:

```
curl -sS https://api.rivier.ai/graphql \
  -H "Authorization: Bearer $RIVIER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "query": "{ __schema { queryType { name } } }" }'
```

## Schema

Read the schema by introspection with any key except a publishable one. Field names follow the operations: the read `search.web.search` is `Query.searchWebSearch`, and the write `analytics.monitor.create` is `Mutation.analyticsMonitorCreate`. The OpenAPI document names the field of each operation in `x-rivier-graphql`.

## Limits

One request may go 8 levels deep, ask for 12 root fields and be 32,000 characters long. Each request also has a cost, counted from the fields it asks for, with a ceiling of 600. A request over a limit answers 400 and says which limit. The rate limit of the key counts GraphQL requests too.

## Persisted queries

Send the SHA-256 of a query in `extensions.persistedQuery.sha256Hash` to run a query the server already holds. If it does not hold it, the answer is the error `PERSISTED_QUERY_NOT_FOUND`; send the query text with the hash once and use the hash alone after that.

Body:

```
{
  "extensions": {
    "persistedQuery": { "sha256Hash": "…" }
  }
}
```

## Errors

Errors are in the `errors` list, each with `extensions.code`: `GRAPHQL_VALIDATION_FAILED`, `FORBIDDEN`, `BAD_REQUEST`, `RATE_LIMITED`, `QUOTA_EXCEEDED` or `INTERNAL`.
