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

# Generate API Tokens

Create a scoped token so your server can call the LearnCard API without holding a seed.

{% hint style="info" %}
**\~5 min** · After the [Quickstart](/start-here/your-first-integration.md).
{% endhint %}

## The one-line version

```bash
npx @learncard/cli token --scope boosts:write
```

Creates the auth grant, shows the token once, saves it to `.env` (`chmod 600`), and writes `send.sh` — a ready-to-run `curl` that reads the token from `.env`. Add `--expires 30` for a 30-day token. `--list` shows your grants; `--revoke <grantId>` revokes one.

An API token is a bearer credential tied to an **auth grant** (a named set of scopes on your profile). Use it for `POST /api/send` and other REST calls from any language; the SDK with a seed doesn't need one. See [Auth Grants and API Tokens](/understand/decentralized-identifiers-dids/auth-grants-and-api-tokens.md).

{% tabs %}
{% tab title="Developer Portal (no code)" %}

1. Sign in at <https://learncard.app/app-store/developer>.
2. Open your integration and go to the **API Tokens** tab.
3. Click **Create**, provide a name, scope (e.g., `boosts:write`), and optional expiry.
4. Copy the token (it is shown only once).
   {% endtab %}

{% tab title="Script" %}

```typescript
// 1. Create an AuthGrant with specific permissions
const grantId = await learnCard.invoke.addAuthGrant({
    name: 'Credential Sender Auth',
    scope: 'boosts:write',
});

// 2. Generate an API token from the AuthGrant
const token = await learnCard.invoke.getAPITokenForAuthGrant(grantId);
```

Then use it in the `Authorization: Bearer <token>` header of your HTTP requests. See [Sign locally, send over HTTP](/build/send-credentials.md#sign-locally-send-over-http) for a runnable example.
{% endtab %}
{% endtabs %}

## Scopes

Scopes define the permissions granted to a client via an API token. Each scope follows the pattern `{resource}:{action}`. You can combine multiple scopes with a space (e.g., `boosts:write inbox:read`).

| Scope          | What it allows                                                       |
| -------------- | -------------------------------------------------------------------- |
| `*:*`          | Full access to all resources                                         |
| `*:read`       | Read-only access to all resources                                    |
| `boosts:write` | Create and send credential templates (required for `POST /api/send`) |
| `inbox:write`  | Send credentials to a user's inbox                                   |
| `contracts:*`  | Manage ConsentFlow contracts                                         |
| `profiles:*`   | Manage the user's profile                                            |

## Rotate or revoke

* **Revoke:** Tokens are revoked by revoking or deleting the auth grant (via the Developer Portal API Tokens tab, or `learnCard.invoke.revokeAuthGrant(id)` / `deleteAuthGrant(id)`).
* **Expire:** Set an expiry when creating the grant to automatically invalidate the token.
* **Isolate:** Use one grant per system so you can rotate them independently.

## What you should see

A JWT — three base64 segments separated by dots. Put it in `Authorization: Bearer <token>`. Test it in one line:

```bash
curl -s https://network.learncard.com/api/profile -H "Authorization: Bearer $TOKEN"
```

Your profile comes back as JSON; a `401` means the token is wrong or expired.

## Troubleshooting

| If…                | Then                                                                                                  |
| ------------------ | ----------------------------------------------------------------------------------------------------- |
| `401 Unauthorized` | Ensure your API token is included in the `Authorization: Bearer <token>` header and hasn't expired.   |
| `403 Forbidden`    | Check that your token has the correct scope (e.g., `boosts:write` for sending credentials).           |
| `Invalid grant ID` | Verify that the `grantId` you passed to `getAPITokenForAuthGrant` exists and belongs to your profile. |

## Next steps

* [Send Signed Credentials over HTTP](/build/send-credentials.md#sign-locally-send-over-http)
* [Go to Production](/build/go-to-production.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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.learncard.com/build/go-to-production/generate-api-tokens.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
