> For the complete documentation index, see [llms.txt](https://learning.contextqa.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://learning.contextqa.com/administration/api-tokens.md).

# API Tokens

## Quick answer

Create, scope, and manage API tokens in ContextQA — long-lived credentials for scripts and integrations, with permission scopes, expiry, and an IP allowlist. Use this page to understand when the capability applies, complete its user-facing workflow, and verify the expected result.

## What this page covers

{% hint style="info" %}
**Who is this for?** SDETs, developers, and administrators who need to call the ContextQA API from scripts, CI/CD pipelines, or other integrations.
{% endhint %}

API tokens are scoped, long-lived credentials that authenticate automated calls to the ContextQA API. Each token carries a fixed set of permission scopes, an expiry, and an optional IP allowlist, so you can grant an integration exactly the access it needs and no more.

Open **Settings → API Tokens** to manage them. You only see tokens you created — each entry lists its name, creator, permissions, expiry, last use, and status.

![API Tokens page with search, status filtering, rate limits, and the Create token action](/files/0qcDEjxPslSW9itUOqon)

{% hint style="info" %}
API tokens are separate from the organization-level API key and secret shown under **Settings → Authentication Configuration**, and from the OAuth sign-in used by the [ContextQA MCP Server](/mcp-server/authentication.md). Use an API token when a script or integration needs its own scoped, revocable credential.
{% endhint %}

***

## Key concepts

* **Scopes.** Each token grants one or more permission scopes. A scope maps to a fixed set of API routes — for example, **View Test Cases** allows `GET /test_cases/**`. At least one scope is required.
* **Expiry.** A token expires after a preset period, up to a maximum of 180 days. You can also create a token that never expires, though this is not recommended.
* **IP allowlist.** By default a token accepts calls from any IP address. You can restrict it to an explicit list of IPv4 addresses, which is enforced before authentication.
* **One-time value.** The token value appears only once, immediately after you create it. ContextQA does not store it in a readable form, so it cannot be recovered later.
* **Status.** A token is **Active**, **Deactivated**, or **Expired**. You can deactivate and reactivate a token without deleting it.

{% hint style="warning" %}
Only superadmins can create tokens. If your role can't create tokens, the **Create token** button is hidden, but you can still manage tokens you already own.
{% endhint %}

***

## Create a token

1. Go to **Settings → API Tokens**.
2. Click **Create token**.
3. In the **Details** section, enter a recognizable **Name** (for example, `CI Pipeline`). The name can be up to 255 characters.
4. From the **Expires** dropdown, select an expiry period. The default is 30 days.
5. In the **Permissions** section, select the scopes the token needs. Pick the narrowest set that works. See [Permission scopes](#permission-scopes) for the full list.
6. (Optional) In the **IP allowlist** section, restrict the token to specific IP addresses. See [Restrict a token to specific IPs](#restrict-a-token-to-specific-ips).
7. Click **Create token**.

![Create API token page with name, expiry, permission scopes, and the IP allowlist section](/files/UgAsnrvhorgT4LkuPnzi)

ContextQA creates the token and opens the **Token created** dialog with the token value.

{% hint style="info" %}
The name and expiry can't be changed after a token is created — only its permissions and IP allowlist are editable. To change the name or expiry, create a replacement token and delete the old one.
{% endhint %}

***

## Copy and store the token value

When the **Token created** dialog appears:

1. Click **Copy** to copy the token value.
2. Store it in an approved secret manager or your integration's secure configuration.
3. Select the **I have copied the token and stored it somewhere safe** checkbox.
4. Click **Done**.

{% hint style="warning" %}
Copy the token now — it will never be shown again. ContextQA doesn't store the value in a readable form, so support can't recover it. If you lose the value, delete the token and create a new one.
{% endhint %}

***

## Use a token

Send the token as a bearer token in the `Authorization` header of each API request:

```http
Authorization: Bearer <token>
```

Calls that fall outside the token's scopes — or outside its IP allowlist, if you set one — are rejected.

An API token authenticates a request but does not establish an endpoint contract. For CI/CD automation, use only endpoint paths and payloads published in your workspace or an official ContextQA API reference. Do not infer paths from browser network traffic or reuse older username-and-password examples.

***

## Permission scopes

Each scope maps to a fixed set of API routes. Select only the scopes your integration calls.

| Scope                         | Routes                                   |
| ----------------------------- | ---------------------------------------- |
| **View Test Cases**           | `GET /test_cases/**`                     |
| **Create & Edit Test Cases**  | `POST, PUT /test_cases/**`               |
| **View Test Case Results**    | `GET /test_case_results/**`              |
| **View Test Plans**           | `GET /test_plans/**`                     |
| **Create & Edit Test Plans**  | `POST, PUT /test_plans/**`               |
| **View Test Plan Results**    | `GET /test_plan_results/**`              |
| **View Test Suites**          | `GET /test_suites/**`                    |
| **Create & Edit Test Suites** | `POST, PUT /test_suites/**`              |
| **View Test Suite Results**   | `GET /test_suite_results/**`             |
| **View Test Steps**           | `GET /test_steps/**`                     |
| **Create & Edit Test Steps**  | `POST, PUT /test_steps/**`               |
| **View Test Step Results**    | `GET /test_step_results/**`              |
| **Send Email**                | `POST /api/email/send` — high abuse risk |
| **Full Access**               | Every scope above **except Send Email**  |

{% hint style="warning" %}
**Full Access** covers every scope except **Send Email**. Send Email is never implied by Full Access and you must grant it separately. Grant it only when the integration genuinely sends email.
{% endhint %}

***

## Expiry options

Select an expiry when you create the token:

| Option       | Notes           |
| ------------ | --------------- |
| 7 days       |                 |
| 30 days      | Default         |
| 60 days      |                 |
| 90 days      |                 |
| 180 days     | Maximum         |
| Never expire | Not recommended |

The server rejects any expiry beyond 180 days from creation unless **Never expire** is selected.

{% hint style="warning" %}
A token that never expires stays valid indefinitely and never needs renewal — which also means it never stops working if it leaks. Use **Never expire** only when rotation genuinely isn't possible.
{% endhint %}

***

## Restrict a token to specific IPs

By default a token is **Unrestricted** and accepts calls from any IP address. To limit where it can be used:

1. In the **IP allowlist** section, select **Restrict to an allowlist**.
2. Enter an exact IPv4 address (for example, `203.0.113.10`).
3. Click **Add IP address** to add more addresses.
4. Save the token.

Calls from any address not on the list are rejected before authentication.

{% hint style="info" %}
Only exact IPv4 addresses are supported — CIDR ranges and IPv6 are not supported yet. Saving replaces the entire allowlist, so include every address the integration calls from.
{% endhint %}

***

## Edit a token

You can change a token's permissions and IP allowlist after creation. The name and expiry are fixed.

1. Go to **Settings → API Tokens**.
2. Find the token, open its actions menu, and select **Edit permissions**.
3. Update the scopes or IP allowlist.
4. Click **Save changes**.

Permission changes take effect on the token's next request. The IP allowlist is replaced in full.

***

## Deactivate, activate, or delete a token

From the actions menu next to each token:

* **Deactivate token** — turns off an active token without deleting it. Calls made with it are rejected until you reactivate it.
* **Activate token** — re-enables a deactivated token.
* **Delete token** — permanently removes the token. This can't be undone.

{% hint style="info" %}
Deleting a token is permanent. Any integration still using it stops working immediately. If you only need to pause access, deactivate the token instead.
{% endhint %}

***

## Find a token

The API Tokens table supports searching and filtering:

* **Search by name** — type in the search bar to filter by token name.
* **Status** — filter by **All statuses**, **Active**, **Deactivated**, or **Expired**.

***

## Rate limits

API tokens are subject to rate limits:

* **120 requests per minute** across the API.
* **10 emails per hour** for the **Send Email** scope.

***

## Security best practices

* Give each integration its own token so you can revoke one without affecting others.
* Grant the narrowest set of scopes that works, and avoid **Full Access** unless the integration truly needs it.
* Set the shortest practical expiry and rotate tokens before they lapse.
* Restrict tokens to a known IP allowlist wherever the caller's addresses are stable.
* Store token values in an approved secret manager — never in source control or shared configuration.
* Delete or deactivate a token immediately if it may be exposed.

***

## Related pages

* [Authentication and SSO](/administration/sso-and-authentication.md)
* [Roles & Permissions](/administration/roles-and-permissions.md)
* [Authenticate with the ContextQA MCP server](/mcp-server/authentication.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://learning.contextqa.com/administration/api-tokens.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
