> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.revvue.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.revvue.ai/_mcp/server.

# Making requests

The RevVue API is a federated GraphQL API: inbox, reviews, surveys, bookings, analytics, documents, notifications, and the AI agent are separate services behind the scenes, but you always talk to a single endpoint with a single token.

**Endpoint:** `https://api.revvue.ai/graphql` — if you were given a different endpoint for your environment, use that instead.

Send a `POST` request with a JSON body containing `query` and (optionally) `variables`:

**`curl`**

```bash title="curl"
curl https://api.revvue.ai/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $REVVUE_TOKEN" \
  -d '{
    "query": "query Reviews($limit: Int) { processedReviews(queryLimit: $limit, isTextInReview: true) { count documents { id reviewerName rating source reviewTime } } }",
    "variables": { "limit": 5 }
  }'
```

**`TypeScript`**

```typescript title="TypeScript"
const res = await fetch("https://api.revvue.ai/graphql", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.REVVUE_TOKEN}`,
  },
  body: JSON.stringify({
    query: `
      query Reviews($limit: Int) {
        processedReviews(queryLimit: $limit, isTextInReview: true) {
          count
          documents { id reviewerName rating source reviewTime }
        }
      }
    `,
    variables: { limit: 5 },
  }),
});
const { data, errors } = await res.json();
```

**`Python`**

```python title="Python"
import os, requests

res = requests.post(
    "https://api.revvue.ai/graphql",
    headers={"Authorization": f"Bearer {os.environ['REVVUE_TOKEN']}"},
    json={
        "query": """
          query Reviews($limit: Int) {
            processedReviews(queryLimit: $limit, isTextInReview: true) {
              count
              documents { id reviewerName rating source reviewTime }
            }
          }
        """,
        "variables": {"limit": 5},
    },
)
payload = res.json()
```

## Conventions

A few patterns repeat across the whole API:

* **Pagination** — list queries take `queryOffset` and `queryLimit` (start index and page size) and usually return a wrapper type with `documents` and a total `count`. Some queries also accept `countOnly: true` to fetch just the count.
* **Sorting** — pass `orderBy: [{ sortField: ..., descOrder: true }]` where supported.
* **Filtering** — most document queries accept typed filter arguments (dates, sources, statuses) plus a generic `filters` list combined with `filterOperator: AND | OR`, and `freeTextSearch` for keyword search.
* **Soft deletion** — documents carry an `activeState` of `ACTIVE`, `INACTIVE`, or `DELETED`; queries take an `activeState` argument to control which you see.
* **IDs** — documents use `UUID` ids. `tenantId` scopes everything; companies and locations form the hierarchy below it.

## Errors

Errors come back GraphQL-style: a `200` response with an `errors` array alongside (or instead of) `data`. Each error has a `message` and a `path` pointing at the field that failed. Authentication failures on protected fields surface here too, so always check `errors` before trusting a partial `data` payload.

## Explore the API

The [API reference](/api-reference) documents every query, mutation, subscription, and type — generated directly from the live schema.