Skip to content

Authentication

The 0.link API uses API key-based authentication for secure access to your resources. This guide covers authentication methods, security best practices, and troubleshooting.

API Key Format

0.link API keys use this format:

zlk_live_<keyid>.<secret>
  • zlk_live_: Prefix indicating a live/production key
  • <keyid>: 12-character base64url identifier
  • <secret>: 43-character base64url secret

Example:

zlk_live_abc123xyz789.dGhpcyBpcyBhIHNhbXBsZSBzZWNyZXQga2V5MTIzNDU2Nzg5MA

Token Shown Once

Your API token is displayed only once when created. Store it immediately in a secure location. You cannot retrieve the token later - you will need to create a new key if lost.

Authentication Methods

Include your API key in the Authorization header using the Bearer token format:

bash
curl -H "Authorization: Bearer zlk_live_abc123xyz789.your_secret_here" \
     https://api.0.link/api/domains

Complete Example

bash
curl -X GET \
  -H "Authorization: Bearer zlk_live_abc123xyz789.your_secret_here" \
  -H "Content-Type: application/json" \
  https://api.0.link/api/domains

Query Parameter (Alternative)

You can also pass the token as a query parameter:

bash
curl "https://api.0.link/api/domains?token=zlk_live_abc123xyz789.your_secret_here"

TIP

The Authorization header method is recommended as it keeps tokens out of server logs and browser history.

Code Examples

JavaScript (fetch)

javascript
const response = await fetch('https://api.0.link/api/domains', {
  headers: {
    'Authorization': 'Bearer zlk_live_abc123xyz789.your_secret_here',
    'Content-Type': 'application/json'
  }
});

Python (requests)

python
import requests

headers = {
    'Authorization': 'Bearer zlk_live_abc123xyz789.your_secret_here',
    'Content-Type': 'application/json'
}

response = requests.get('https://api.0.link/api/domains', headers=headers)

Node.js (axios)

javascript
import axios from 'axios';

const api = axios.create({
  baseURL: 'https://api.0.link/api',
  headers: {
    'Authorization': 'Bearer zlk_live_abc123xyz789.your_secret_here'
  }
});

const domains = await api.get('/domains');

API Key Scopes

When creating an API key, you can assign one of three scopes:

ScopeDescriptionUse Case
READRead-only accessMonitoring, reporting integrations
WRITERead and write accessAutomated domain management
ADMINFull administrative access (default)Trusted applications with full control

Note: If no scope is specified, ADMIN is used by default.

Scope Examples

json
{
  "endpoint": "GET /api/domains",
  "required_scope": "READ",
  "api_key_scope": "READ",
  "result": "allowed"
}
json
{
  "endpoint": "POST /api/domains",
  "required_scope": "WRITE",
  "api_key_scope": "READ",
  "result": "denied"
}

Authentication Flow

1. API Key Validation

Every request validates your API key:

mermaid
graph LR
    A[Client Request] --> B{Valid API Key?}
    B -->|Yes| C{Has Required Scope?}
    B -->|No| D[401 Unauthorized]
    C -->|Yes| E[Process Request]
    C -->|No| F[403 Forbidden]

2. Permission Check

After authentication, the API checks if your key has the required scope:

  • READ scope: Can access GET endpoints
  • WRITE scope: Can access GET, POST, PUT, DELETE endpoints
  • ADMIN scope: Full access to all endpoints

3. Request Processing

Valid, authorized requests are processed and return data:

json
{
  "id": "dom_abc123",
  "name": "example.com",
  "status": "active"
}

Token Lifecycle

Creation

When you create an API key through the dashboard or API:

  1. A unique key ID and secret are generated
  2. The full token (zlk_live_<keyid>.<secret>) is displayed once
  3. Only the key ID and metadata are stored - the secret cannot be retrieved later

Rotation

To rotate your API key securely:

  1. Create a new key with the same scope
  2. Update your applications to use the new key
  3. Test thoroughly to verify the new key works
  4. Revoke the old key once migration is complete

Grace Period

When revoking a key, consider the timing carefully. The key becomes invalid immediately upon revocation.

Revocation

Revoke keys immediately if:

  • A key is compromised
  • An employee leaves the organization
  • A key is no longer needed
  • You detect suspicious activity

Security Best Practices

Key Storage

bash
# .env file
ZEROLINK_API_KEY=zlk_live_abc123xyz789.your_secret_here
javascript
const apiKey = process.env.ZEROLINK_API_KEY;
if (!apiKey) {
  throw new Error('API key not configured');
}

Never Hardcode Keys

javascript
// DON'T DO THIS
const apiKey = 'zlk_live_abc123xyz789.your_secret_here'; // Never hardcode

Never Commit to Version Control

bash
# Add to .gitignore
.env
.env.local
*.env

Access Control

Use the principle of least privilege:

EnvironmentRecommended ScopeUsage
DevelopmentREADTesting and debugging
StagingWRITEPre-production testing
Production (read-only)READMonitoring dashboards
Production (automation)WRITEAutomated workflows
Admin tasksADMINUse sparingly

Key Management

  • Rotate keys regularly (every 90 days recommended)
  • Use different keys for different environments
  • Monitor key usage for anomalies
  • Never log API keys
  • Never share keys via email or chat

Error Handling

401 Unauthorized

Cause: Missing or invalid API key

json
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Authentication required"
  }
}

Common Causes:

  • Missing Authorization header
  • Malformed API key format
  • Deleted or revoked API key
  • Incorrect Bearer token format

Solutions:

bash
# Check header format
curl -H "Authorization: Bearer zlk_live_..." # Correct
curl -H "Authorization: zlk_live_..." # Missing "Bearer"
curl -H "Api-Key: zlk_live_..." # Wrong header name

403 Forbidden

Cause: Valid key but insufficient scope

json
{
  "error": {
    "code": "INSUFFICIENT_SCOPE",
    "message": "This action requires WRITE scope",
    "required_scope": "WRITE",
    "current_scope": "READ"
  }
}

Solutions:

  • Create a new API key with the appropriate scope
  • Use a different key with the required scope

429 Rate Limited

Cause: Too many requests

json
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests",
    "retry_after": 60
  }
}

Solutions:

  • Implement exponential backoff
  • Reduce request frequency
  • Contact support for higher limits

Testing Authentication

Verify API Key

Test your API key by listing your domains:

bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
     https://api.0.link/api/domains

Expected response (if you have domains):

json
[
  {
    "id": "dom_abc123",
    "name": "example.com",
    "status": "active"
  }
]

Or an empty array if you have no domains:

json
[]

IP Tracking

API key usage is tracked by IP address for security monitoring. This helps detect:

  • Unusual access patterns
  • Potential unauthorized use
  • Geographic anomalies

Troubleshooting

Common Issues

"Invalid API Key" Errors

  • Verify the key is copied correctly (no extra spaces)
  • Check key hasn't been revoked in dashboard
  • Ensure you're using the full token including the secret portion

"Forbidden" Errors

  • Check the required scope for the endpoint
  • Verify your key has the appropriate scope
  • Ensure your account has access to the resource

Intermittent Authentication Failures

  • Check for network connectivity issues
  • Verify system clock is synchronized
  • Look for rate limiting responses

Contact Support

For authentication issues:

Next Steps