> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zivio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Get an access token and make your first request

### Before you start

You need two things from your Zivio administrator (or
[support@zivio.com](mailto:support@zivio.com)):

* An **OAuth client** — a client ID and client secret. Tell them which
  [scopes](/v4/scopes) your integration needs.
* Your **organisation identifier**, sent as the `zivio-tenant-id` header on every request.
  The regional API endpoints serve every Zivio organisation, so each request has to say which
  one it is for. See [Identifying your organisation](/v4/authentication#identifying-your-organisation).

<Warning>
  The client secret is shown once when the client is created. Store it somewhere secure; it
  cannot be retrieved again.
</Warning>

<Steps>
  <Step title="Exchange your credentials for an access token">
    Post your credentials to the token endpoint, listing the scopes you want as a
    space-separated string.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.zivio.net/api/v4/oauth/token \
        -H "zivio-tenant-id: $ZIVIO_TENANT_ID" \
        -H "Content-Type: application/x-www-form-urlencoded" \
        -d grant_type=client_credentials \
        -d client_id=$ZIVIO_CLIENT_ID \
        -d client_secret=$ZIVIO_CLIENT_SECRET \
        -d scope="welcome:read projects:read"
      ```

      ```python Python theme={null}
      import os, requests

      resp = requests.post(
          "https://api.zivio.net/api/v4/oauth/token",
          headers={"zivio-tenant-id": os.environ["ZIVIO_TENANT_ID"]},
          data={
              "grant_type": "client_credentials",
              "client_id": os.environ["ZIVIO_CLIENT_ID"],
              "client_secret": os.environ["ZIVIO_CLIENT_SECRET"],
              "scope": "welcome:read projects:read",
          },
      )
      token = resp.json()["access_token"]
      ```

      ```javascript Node.js theme={null}
      const resp = await fetch("https://api.zivio.net/api/v4/oauth/token", {
        method: "POST",
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
          "zivio-tenant-id": process.env.ZIVIO_TENANT_ID,
        },
        body: new URLSearchParams({
          grant_type: "client_credentials",
          client_id: process.env.ZIVIO_CLIENT_ID,
          client_secret: process.env.ZIVIO_CLIENT_SECRET,
          scope: "welcome:read projects:read",
        }),
      });
      const { access_token } = await resp.json();
      ```
    </CodeGroup>

    The response carries the token and its lifetime:

    ```json theme={null}
    {
      "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "token_type": "Bearer",
      "expires_in": 7200,
      "scope": "welcome:read projects:read"
    }
    ```

    <Tip>
      A `404 Tenant Unknown` here means the `zivio-tenant-id` header is missing or wrong — it
      is checked before your credentials are.
    </Tip>

    <Tip>
      Check the `scope` field in the response. You are granted the intersection of what you
      asked for and what your client is allowed — asking for more than you hold does not fail,
      it just returns less.
    </Tip>
  </Step>

  <Step title="Confirm the token works">
    `GET /welcome` is the whoami endpoint. It tells you which user the token acts as and which
    scopes were granted, which makes it the right first call in any integration.

    ```bash theme={null}
    curl https://api.zivio.net/api/v4/welcome \
      -H "Authorization: Bearer $ACCESS_TOKEN" \
      -H "zivio-tenant-id: $ZIVIO_TENANT_ID"
    ```

    ```json theme={null}
    {
      "message": "Welcome to Zivio",
      "owner": { "id": 12345, "email": "api-user@company.com" },
      "scopes": "welcome:read projects:read"
    }
    ```
  </Step>

  <Step title="Make a real request">
    Send the token as a bearer token on every subsequent call.

    ```bash theme={null}
    curl "https://api.zivio.net/api/v4/projects?limit=5&sort[created_at]=desc" \
      -H "Authorization: Bearer $ACCESS_TOKEN" \
      -H "zivio-tenant-id: $ZIVIO_TENANT_ID"
    ```

    This needs the `projects:read` scope. If you left it out of your token request you will
    get a `403` with `error: insufficient_scope` naming the scope you need.
  </Step>

  <Step title="Discover what you can filter">
    Every resource has a `/help` endpoint listing its filterable attributes, operators and
    enum values — no guesswork required.

    ```bash theme={null}
    curl https://api.zivio.net/api/v4/projects/help \
      -H "Authorization: Bearer $ACCESS_TOKEN" \
      -H "zivio-tenant-id: $ZIVIO_TENANT_ID"
    ```

    See [Filtering and pagination](/v4/filtering-and-pagination) for the query syntax.
  </Step>
</Steps>

### Next steps

<CardGroup cols={2}>
  <Card title="Scopes" icon="shield-check" href="/v4/scopes">
    Pick the narrowest set your integration needs.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/v4/projects/list-projects">
    Every endpoint, with a request playground.
  </Card>
</CardGroup>
