# Get Token API

> Get the token of an API user or of a person from API Maker with the token API - username and password, or the name of a token generator, refresh tokens, several tokens in one call, and tenant tokens.

Source: https://docs.apimaker.dev/v4/docs/apis-all/system-apis/system-generated-token-api.html

Gives the two tokens every call may need : the token of an **API user** (which application calls, sent in `x-am-authorization`) and the token of a **person**, a row of your own users table read by a DB token generator (sent in `x-am-user-authorization`). See [the two gates](https://docs.apimaker.dev/v4/docs/getting-started/how-it-works.html#the-two-gates).

| | |
|---|---|
| Method | POST |
| URL | `/api/system-api/admin/token` : `admin` is the user path of your account |
| Body | `{ u, p, expiresInSeconds? }`, `{ name, u, p }`, `{ refresh_token, name? }`, or an array of them |
| Answer | `data` : `{ token, refresh_token, expires_in }`, or an array |
| From code | [`g.sys.system.getToken`](https://docs.apimaker.dev/v4/docs/apis-all/system-apis/system-generated-token-api.html#from-code) |

## The token of an API user

**Body : without name, an API user of API Maker**

```json
{ "u": "default", "p": "12345", "expiresInSeconds": 259200 }
```

**Answer**

```json
{ "success": true, "statusCode": 200, "data": { "token": "eyJhbGciOi…", "refresh_token": "eyJhbGciOi…", "expires_in": 259200 } }
```

- `expiresInSeconds` is optional : **Tokens Expire After** of the [Deployment Settings](https://docs.apimaker.dev/v4/docs/am-resources/api-maker-configurations.html#security-apis) otherwise (72 hours by default).
- The password of an API user lives in the secret, under the path set on the API user (`common.apiUserPasswords.default` for the API user of a new account).

## The token of a person

**Body : with the name of a token generator**

```json
{ "name": "users_tg", "u": "alice@acme.com", "p": "PASSWORD" }
```

- The generator (an [auth provider](https://docs.apimaker.dev/v4/docs/authorization/AMDB.html) of type DB) knows the users table and its username and password columns. A hashed password column works : the password given is hashed and compared.
- The groups of the person come from the groups column of the generator.

## Refresh

```json
{ "name": "users_tg", "refresh_token": "eyJhbGciOi…" }
```

- `refresh_token` of an earlier answer gives a new token without the password. For a person, add the `name` of the generator. A refresh token is valid `refreshTokenValidForS` seconds (900 by default) after the token expired.

## Several tokens in one call

```json
[
    { "u": "default", "p": "12345" },
    { "name": "users_tg", "u": "alice@acme.com", "p": "PASSWORD" }
]
```

- The answer is an array in the same order. The sample custom API `/default/login` of a new account does exactly this and returns both tokens to the app.

## The token of a tenant user

```text
POST /api/system-api/admin/token
x-am-tenant-username: acme

{ "name": "users_tg", "u": "alice@acme.com", "p": "PASSWORD" }
```

- When the generator reads a users table of a [multi-tenant](https://docs.apimaker.dev/v4/docs/features/multi-tenant.html) instance, name the tenant : the person is read from the database of that tenant, and the token works for that tenant only, also after a refresh.

## From code

`g.sys.system.getToken` makes the same call from your code, whatever the settings of the token API say about HTTP callers.

### The token of an API user

- Token of an API Maker API user: no `name`.

**TypeScript**

```typescript
const apiUser = await g.sys.system.getToken({
    "u": "USER_NAME",
    "p": "USER_PASSWORD"
});
// apiUser.token goes in x-am-authorization
```

**Python**

```python
api_user = await g.sys.system.get_token(
    'USER_NAME',
    'USER_PASSWORD',
)
# apiUser.token goes in x-am-authorization
```

**PHP**

```php
$apiUser = $g->sys->system->getToken(
    'USER_NAME',
    'USER_PASSWORD',
);
// apiUser.token goes in x-am-authorization
```

**C#**

```csharp
var apiUser = await g.Sys.System.GetToken(new GetToken("USER_NAME", "USER_PASSWORD"));
// apiUser.token goes in x-am-authorization
```

**Go**

```go
apiUser, err := g.Sys.System.GetToken(am.GetToken{
	U: "USER_NAME",
	P: "USER_PASSWORD",
})
if err != nil {
	return nil, err
}
// apiUser.token goes in x-am-authorization
```

**Rust**

```rust
let api_user = g.sys.system.get_token(GetToken::new("USER_NAME", "USER_PASSWORD"))?;
// apiUser.token goes in x-am-authorization
```

**Java**

```java
var apiUser = g.sys.system.getToken(new GetToken("USER_NAME", "USER_PASSWORD"));
// apiUser.token goes in x-am-authorization
```

**Kotlin**

```kotlin
val apiUser = g.sys.system.getToken(GetToken("USER_NAME", "USER_PASSWORD"))
// apiUser.token goes in x-am-authorization
```

### The token of a person

- Token of a database user (application user): the `name` of its token generator.

**TypeScript**

```typescript
const databaseUser = await g.sys.system.getToken({
    "name": "TOKEN_GENERATOR_NAME",
    "u": "USER_NAME",
    "p": "PASSWORD"
});
// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
```

**Python**

```python
database_user = await g.sys.system.get_token(
    'USER_NAME',
    'PASSWORD',
    name='TOKEN_GENERATOR_NAME',
)
# databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
```

**PHP**

```php
$databaseUser = $g->sys->system->getToken(
    'USER_NAME',
    'PASSWORD',
    name: 'TOKEN_GENERATOR_NAME',
);
// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
```

**C#**

```csharp
var databaseUser = await g.Sys.System.GetToken(new GetToken("USER_NAME", "PASSWORD")
{
    Name = "TOKEN_GENERATOR_NAME",
});
// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
```

**Go**

```go
databaseUser, err := g.Sys.System.GetToken(am.GetToken{
	Name: "TOKEN_GENERATOR_NAME",
	U:    "USER_NAME",
	P:    "PASSWORD",
})
if err != nil {
	return nil, err
}
// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
```

**Rust**

```rust
let database_user = g.sys.system.get_token(
    GetToken::new("USER_NAME", "PASSWORD")
        .name("TOKEN_GENERATOR_NAME"),
)?;
// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
```

**Java**

```java
var databaseUser = g.sys.system.getToken(new GetToken("USER_NAME", "PASSWORD")
    .name("TOKEN_GENERATOR_NAME"));
// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
```

**Kotlin**

```kotlin
val databaseUser = g.sys.system.getToken(
    GetToken("USER_NAME", "PASSWORD")
        .name("TOKEN_GENERATOR_NAME"),
)
// databaseUser.token goes in x-am-user-authorization, databaseUser.refresh_token gets a new one later
```

### Both in one call

- Both at once: an array in, an array of tokens out.

**TypeScript**

```typescript
const [apiUser, databaseUser] = await g.sys.system.getToken([
    { "u": "USER_NAME", "p": "USER_PASSWORD" },
    { "name": "TOKEN_GENERATOR_NAME", "u": "USER_NAME", "p": "PASSWORD" }
]);
// apiUser.token goes in x-am-authorization, databaseUser.token in x-am-user-authorization
```

**Python**

```python
api_user, database_user = await g.sys.system.get_tokens([
    GetToken('USER_NAME', 'USER_PASSWORD'),
    GetToken('USER_NAME', 'PASSWORD', name='TOKEN_GENERATOR_NAME'),
])
# api_user.token goes in x-am-authorization, database_user.token in x-am-user-authorization
```

**PHP**

```php
[$apiUser, $databaseUser] = $g->sys->system->getTokens([
    new GetToken('USER_NAME', 'USER_PASSWORD'),
    new GetToken('USER_NAME', 'PASSWORD', name: 'TOKEN_GENERATOR_NAME'),
]);
// $apiUser->token goes in x-am-authorization, $databaseUser->token in x-am-user-authorization
```

**C#**

```csharp
var tokens = await g.Sys.System.GetTokens([
    new GetToken("USER_NAME", "USER_PASSWORD"),
    new GetToken("USER_NAME", "PASSWORD") { Name = "TOKEN_GENERATOR_NAME" },
]);
var (apiUser, databaseUser) = (tokens[0], tokens[1]);
// apiUser.Token goes in x-am-authorization, databaseUser.Token in x-am-user-authorization
```

**Go**

```go
tokens, err := g.Sys.System.GetTokens([]am.GetToken{
	{U: "USER_NAME", P: "USER_PASSWORD"},
	{Name: "TOKEN_GENERATOR_NAME", U: "USER_NAME", P: "PASSWORD"},
})
if err != nil {
	return nil, err
}
apiUser, databaseUser := tokens[0], tokens[1]
// apiUser.Token goes in x-am-authorization, databaseUser.Token in x-am-user-authorization
```

**Rust**

```rust
let tokens = g.sys.system.get_tokens(vec![
    GetToken::new("USER_NAME", "USER_PASSWORD"),
    GetToken::new("USER_NAME", "PASSWORD").name("TOKEN_GENERATOR_NAME"),
])?;
let (api_user, database_user) = (&tokens[0], &tokens[1]);
// api_user.token goes in x-am-authorization, database_user.token in x-am-user-authorization
```

**Java**

```java
List<TokenResponse> tokens = g.sys.system.getTokens(List.of(
    new GetToken("USER_NAME", "USER_PASSWORD"),
    new GetToken("USER_NAME", "PASSWORD").name("TOKEN_GENERATOR_NAME")));
TokenResponse apiUser = tokens.get(0), databaseUser = tokens.get(1);
// apiUser.getToken() goes in x-am-authorization, databaseUser.getToken() in x-am-user-authorization
```

**Kotlin**

```kotlin
val (apiUser, databaseUser) = g.sys.system.getTokens(
    listOf(
        GetToken("USER_NAME", "USER_PASSWORD"),
        GetToken("USER_NAME", "PASSWORD").name("TOKEN_GENERATOR_NAME"),
    ),
)
// apiUser.token goes in x-am-authorization, databaseUser.token in x-am-user-authorization
```

## Who may call it

- The token API is public by default : anybody can ask for a token with a username and a password.
- When its [system API settings](https://docs.apimaker.dev/v4/docs/settings/systemApiSettings.html) list auth providers, it needs the tokens those settings ask for, like any other API.
- A token is a JWT signed with `passJWT` of the server. Changing the password of the API user, or `passwordChangedAtColumn` of a person, invalidates the tokens made before.

## Access and settings

- Over HTTP, a system API answers once its [settings](https://docs.apimaker.dev/v4/docs/settings/systemApiSettings.html) give it `apiAccessType: TOKEN_ACCESS` (the token of an API user whose [group](https://docs.apimaker.dev/v4/docs/apis-security/api-group-permission.html) grants this system API, in `x-am-authorization`) or `IS_PUBLIC`. Without settings it is `NO_ACCESS` : your code calls it through `g.sys`, the admin panel tests it, and an HTTP call is refused. The token API itself is public unless its settings say otherwise.
- The settings can also cache the answer or require person tokens (`authProviders`) ; [pre and post hooks](https://docs.apimaker.dev/v4/docs/apis-all/hooks/preHook-api.html) run around it like around any API.
- The [request headers](https://docs.apimaker.dev/v4/docs/apis-all/header/requestHeader.html) apply : `x-am-response-case`, `x-am-content-type-response`, `x-am-internationalization`, `x-am-tenant-username`…

## Errors

| Code | When |
|---|---|
| `400` | The body is wrong : the message names the missing or invalid key, `Please provide token request with ['u', 'p'] or ['refresh_token'].` for an incomplete body. |
| `401` | No valid API user token, or the API is `NO_ACCESS` : `You are not authorized to access this API.` |
| `403` | No group grants this system API. |

## Related

- [All APIs at a glance](https://docs.apimaker.dev/v4/docs/apis-all/overview.html) · [Response format](https://docs.apimaker.dev/v4/docs/apis-all/response-format.html) · [System API settings](https://docs.apimaker.dev/v4/docs/settings/systemApiSettings.html) · [System APIs from code](https://docs.apimaker.dev/v4/examples/sys/system/system.html)
