# Authentication

All Skribble APIs use JWT bearer authentication. Obtain a token by logging in with your API credentials, then include it in the `Authorization` header of every request.

## Getting Your Credentials

Before you can authenticate, you need:

1. **API Username**: Your unique identifier
2. **API Key**: Your secret key (never expose this publicly)

You can generate these credentials yourself in the [Admin UI](https://admin.skribble.com).

## API Key Types

| Key Type | Prefix | Purpose | Cost |
|----------|--------|---------|------|
| Demo | `api_demo` | Testing and development | Free |
| Production | `api_production` / `api_prod` | Live transactions | Billable |

:::info

Demo API keys create signatures that have **no legal weight**. Switch to a production key when going live. All transactions made with production keys are billable.

:::

## Obtaining a Token

Make a POST request to the login endpoint:

```bash
curl -X POST "https://api.skribble.com/v2/access/login" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "your-api-username",
    "api-key": "your-api-key"
  }'
```

**Response** (`text/plain`): the token is returned as a plain string, not wrapped in JSON:

```
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
```

This is the same across all APIs (Sign API v2, v3, and Validation API).

:::note

The Validation API requires the `ROLE_VALIDATION_API_USER` role on the API key. Contact Skribble to have this role assigned to your account.

:::

## Using the Token

Include the token in the `Authorization` header for all subsequent requests:

```bash
curl -X GET "https://api.skribble.com/v2/signature-requests" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
```

## Token Lifetime

- Tokens are valid for approximately **20 minutes**
- After expiration, you must obtain a new token
- There is no refresh token mechanism; simply re-authenticate

## Best Practices

### Token Management

1. **Cache tokens**: Reuse tokens until they expire to minimize login calls
2. **Handle expiration gracefully**: Implement automatic re-authentication when you receive a 401 error
3. **Don't hardcode credentials**: Use environment variables or a secrets manager

### Security

1. **Never expose API keys**: Keep them server-side only
2. **Use HTTPS**: All API calls must use HTTPS
3. **Rotate keys periodically**: Contact Skribble to rotate compromised keys
4. **Separate environments**: Use demo keys for testing, production keys for live


## Error Responses

| Status Code | Description | Action |
|-------------|-------------|--------|
| 401 | Invalid credentials or expired token | Check credentials or re-authenticate |
| 403 | Insufficient permissions | Verify API key has required access |
| 429 | Rate limit exceeded | Implement backoff and retry |
