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

# API Quickstart

> Send your first authenticated request to the TestDino API. Generate a PAT and call /token-info to verify.

The TestDino Public API uses personal access tokens (PATs) for authentication. Every request sends the token as a Bearer header. This quickstart walks through generating a token, verifying it, and calling your first data endpoint.

## Prerequisites

* A TestDino account with at least one project ([sign up](https://app.testdino.com/auth/signup?utm_source=documentation))
* Access to a project the PAT can read

## Steps

<Steps>
  <Step title="Generate a PAT">
    * Sign in to TestDino, open your profile, then **User Settings**
    * Go to **Personal Access Tokens** and **Generate new token**
    * Name it, select the organizations and projects it may access, pick an expiration of 30, 60, 90, or 180 days, and create it

    The `td_pat_` token is shown once, so copy it right away.

    Full workflow: [Generate API keys](/guides/generate-api-keys).
  </Step>

  <Step title="Get ProjectID">
    * Open the project in the <a href="https://app.testdino.com" target="_blank" rel="noopener noreferrer">TestDino App <Icon icon="arrow-up-right-from-square" size={12} /></a>
    * Copy the `project_...` segment from the URL

    Eg: `.../projects/project_69e1bb123.../test-runs`

    <Tip>
      **Tip**

      For CI/CD or automation, export `TESTDINO_API_TOKEN` and `TESTDINO_PROJECT_ID` as env vars, and keep the token as a secret.
    </Tip>
  </Step>

  <Step title="Verify the token">
    Call `/token-info` to confirm the token is valid and scoped correctly:

    <Tabs>
      <Tab title="curl">
        ```bash theme={null}
        curl "https://api.testdino.com/api/v1/public/$TESTDINO_PROJECT_ID/token-info" \
          -H "Authorization: Bearer $TESTDINO_API_TOKEN"
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={null}
        const res = await fetch(
          `https://api.testdino.com/api/v1/public/${process.env.TESTDINO_PROJECT_ID}/token-info`,
          { headers: { Authorization: `Bearer ${process.env.TESTDINO_API_TOKEN}` } }
        );
        const data = await res.json();
        console.log(data);
        ```
      </Tab>

      <Tab title="Python">
        ```python theme={null}
        import os, requests

        res = requests.get(
            f"https://api.testdino.com/api/v1/public/{os.environ['TESTDINO_PROJECT_ID']}/token-info",
            headers={"Authorization": f"Bearer {os.environ['TESTDINO_API_TOKEN']}"},
        )
        print(res.json())
        ```
      </Tab>
    </Tabs>

    A `200 OK` response with `success: true` confirms the setup is working.
  </Step>

  <Step title="Call a data endpoint">
    List the 5 most recent test runs:

    <Tabs>
      <Tab title="curl">
        ```bash theme={null}
        curl "https://api.testdino.com/api/v1/public/$TESTDINO_PROJECT_ID/test-runs?limit=5" \
          -H "Authorization: Bearer $TESTDINO_API_TOKEN"
        ```
      </Tab>

      <Tab title="Node.js">
        ```javascript theme={null}
        const res = await fetch(
          `https://api.testdino.com/api/v1/public/${process.env.TESTDINO_PROJECT_ID}/test-runs?limit=5`,
          { headers: { Authorization: `Bearer ${process.env.TESTDINO_API_TOKEN}` } }
        );
        const { data, pagination } = await res.json();
        console.log(`Showing ${data.length} of ${pagination.total} runs`);
        ```
      </Tab>

      <Tab title="Python">
        ```python theme={null}
        import os, requests

        res = requests.get(
            f"https://api.testdino.com/api/v1/public/{os.environ['TESTDINO_PROJECT_ID']}/test-runs?limit=5",
            headers={"Authorization": f"Bearer {os.environ['TESTDINO_API_TOKEN']}"},
        )
        body = res.json()
        print(f"Showing {len(body['data'])} of {body['pagination']['total']} runs")
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

## Troubleshooting

<AccordionGroup>
  <Accordion title="401 UNAUTHORIZED">
    The header is missing, the token does not start with `td_pat_`, or the token is not recognized. Check:

    * Header is `Authorization: Bearer td_pat_...` (case-sensitive, single space)
    * The token starts with `td_pat_`
    * The token has not been rotated or deleted in User Settings
  </Accordion>

  <Accordion title="401 TOKEN_REVOKED or 401 TOKEN_EXPIRED">
    The token was revoked, or it passed its expiry date. Generate a new PAT in **User Settings → Personal Access Tokens** and update your stored secret.
  </Accordion>

  <Accordion title="404 NOT_FOUND">
    The resource does not exist, or the token does not cover the `projectId` in the URL. Use a PAT that was granted access to that project.
  </Accordion>

  <Accordion title="429 RATE_LIMIT_EXCEEDED">
    You've hit the 100 requests/minute per-token limit. Wait for the `RateLimit-Reset` timestamp in the response headers, or implement exponential backoff. See [Rate limits](/api-reference/conventions#rate-limits).
  </Accordion>
</AccordionGroup>
