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

# OAuth apps

> One app installed in many tenants, with a one-hour token and no pasted secret.

An API key suits a customer's own systems. A vendor whose product is used by many andteam tenants, such
as an ATS, uses an **OAuth app** instead. The vendor registers once, each tenant's administrator
installs it, and the vendor never holds a secret pasted from the tenant. The grant is client
credentials: the app acts for itself in one tenant at a time.

## How an app gets installed

1. **andteam registers the app.** The vendor tells andteam its name and the field groups it asks for,
   each at Read or Write. andteam gives the vendor a `client_id` and a `client_secret`. The secret is
   shown once.
2. **A tenant administrator installs it** under **Settings**, **Integrations**, **Apps**. The administrator
   chooses the companies and field groups, **no more than the app asks for**. Read where the app asks for
   Write is fine. Write where it asks only for Read is not.
3. An install follows the same rules as a key. A group that needs approval waits for its approver, and
   an install with a Write switch names a requester. See [Approvals](https://docs.andteam.com/concepts/approvals.md) and
   [Making changes](https://docs.andteam.com/guides/writes.md).

## Get a token

```bash theme={null}
curl -X POST "https://api.v3.andteam.com/v1/oauth/token" \
  -d grant_type=client_credentials \
  -d tenant=acme \
  -d client_id=oac_… \
  -d client_secret=ocs_…
```

The request is `application/x-www-form-urlencoded`.

| Parameter | Meaning |
| - | - |
| `grant_type` | Always `client_credentials`. |
| `tenant` | The tenant's andteam subdomain, such as `acme` for `acme.andteam.com`. |
| `client_id`, `client_secret` | The app's credentials, in the body or as HTTP Basic. |

The answer carries `access_token`, `token_type` (`Bearer`), `expires_in` and `scope`. The token starts
`ato_` and is valid for **one hour**. It carries the install's companies and field groups. Ask for a new
one when it expires.

## Call the API

Send the token as a key is sent:

```text theme={null}
Authorization: Bearer ato_…
```

Everything else is the same as for a key: field groups, [rate limits](https://docs.andteam.com/rate-limits.md), the write rules and
[problem types](https://docs.andteam.com/errors.md). An expired or unknown token is a 401 problem.

## Errors

The token endpoint answers with RFC 6749 errors, not problem details: JSON with `error` and
`error_description`.

| Status | `error` | Cause |
| - | - | - |
| 400 | `unsupported_grant_type` | `grant_type` is not `client_credentials`. |
| 400 | `invalid_request` | `tenant` is missing. |
| 400 | `unauthorized_client` | The app is not installed in that tenant, or it was uninstalled. |
| 401 | `invalid_client` | The client is unknown or retired, or the secret is wrong. |

## Uninstall and rolling the secret

**Uninstalling an app stops its tokens at once.** No new token is issued for that tenant.

When andteam rolls an app's secret, the **old secret keeps working for 24 hours**, so the vendor can
swap it without an outage. After that it answers `invalid_client`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.