Skip to content

API Access

Understanding API access levels and permissions is essential for building applications with 0.link. This guide covers API key scopes, permission management, and how to handle access-related errors.

API Key Scopes

Every API key has a scope that determines what operations it can perform. 0.link uses three scope levels:

ScopeDescriptionCapabilities
READRead-only accessView domains, list DNS records, search availability
WRITERead and write accessAll READ operations, plus register domains, create/update DNS records, modify domain settings
ADMINFull administrative accessAll WRITE operations, plus manage API keys, account settings

Default Scope

When creating an API key without specifying a scope, it defaults to ADMIN. For production applications, we recommend using the minimum scope required.

Read-Only Access (READ Scope)

What You Can Do

With a READ scope API key:

javascript
// ✅ List your domains
const response = await fetch('https://api.0.link/api/domains', {
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const domains = await response.json();

// ✅ Get domain details
const domain = await fetch('https://api.0.link/api/domains/dom_abc123', {
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(res => res.json());

// ✅ List DNS records
const records = await fetch('https://api.0.link/api/domains/dom_abc123/dns/records', {
  headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
}).then(res => res.json());

// ✅ Search domain availability
const availability = await fetch('https://api.0.link/api/domains/search', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ query: 'mysite', tlds: ['com', 'io'] })
}).then(res => res.json());

What You Cannot Do

javascript
// ❌ Register a domain
await fetch('https://api.0.link/api/domains', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'example.com', years: 1, contacts: { ... } })
});
// Error: 403 Forbidden - WRITE scope required

// ❌ Create DNS records
await fetch('https://api.0.link/api/domains/dom_abc123/dns/records', {
  method: 'POST',
  headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({ type: 'A', name: '@', content: '192.0.2.1' })
});
// Error: 403 Forbidden - WRITE scope required

Use Cases for READ Scope

  • Monitoring dashboards: Display domain expiration dates and DNS status
  • Availability checkers: Build tools to search for available domains
  • Reporting systems: Generate reports from domain and DNS data
  • Third-party integrations: Sync domain data to external systems

Read-Write Access (WRITE Scope)

Additional Capabilities

With a WRITE scope API key, you can also:

javascript
// ✅ Register a new domain
const newDomain = await fetch('https://api.0.link/api/domains', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'example.com',
    years: 1,
    contacts: {
      registrant: {
        first_name: 'John',
        last_name: 'Doe',
        email: '[email protected]',
        phone: '+1.5551234567',
        address: {
          street: '123 Main St',
          city: 'San Francisco',
          state: 'CA',
          postal_code: '94102',
          country: 'US'
        }
      }
    }
  })
}).then(res => res.json());

// ✅ Create DNS records
const record = await fetch('https://api.0.link/api/domains/dom_abc123/dns/records', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    type: 'A',
    name: '@',
    content: '192.0.2.1',
    ttl: 3600
  })
}).then(res => res.json());

// ✅ Update nameservers
await fetch('https://api.0.link/api/domains/dom_abc123/nameservers', {
  method: 'PUT',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    nameservers: ['ns1.cloudflare.com', 'ns2.cloudflare.com']
  })
});

// ✅ Update auto-renew setting
await fetch('https://api.0.link/api/domains/dom_abc123/autorenew', {
  method: 'PUT',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ auto_renew: true })
});

// ✅ Renew a domain
await fetch('https://api.0.link/api/domains/dom_abc123/renew', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ years: 1 })
});

Use Cases for WRITE Scope

  • Domain management platforms: Register and configure domains
  • Automated DNS management: Deploy DNS changes programmatically
  • Infrastructure automation: Manage domains as part of CI/CD pipelines
  • Reseller applications: Build domain reseller tools

Administrative Access (ADMIN Scope)

Additional Capabilities

With an ADMIN scope API key, you can also manage API keys programmatically via GraphQL:

graphql
# List all API keys
query {
  apiKeys {
    keyId
    name
    scope
    createdAt
    lastUsedAt
    validFrom
    validUntil
  }
}

# Create a new API key
mutation {
  issueApiKey(name: "Production Backend", scope: WRITE) {
    keyId
    token  # Only shown once - store securely!
    name
    scope
    validFrom
  }
}

# Rotate an existing API key
mutation {
  rotateApiKey(keyId: "abc123", graceSeconds: 3600) {
    keyId
    token  # New token - update your applications
    name
    scope
  }
}

# Revoke an API key
mutation {
  revokeApiKey(keyId: "abc123")
}

Use Cases for ADMIN Scope

  • API key management: Programmatically create and rotate keys
  • Administrative tools: Build internal tools for account management
  • Security automation: Automatically rotate keys on a schedule

Managing API Keys

Creating Keys in Dashboard

  1. Navigate to API Keys in your 0.link dashboard
  2. Click Create API Key
  3. Enter a descriptive name (e.g., "Production Backend")
  4. Select the appropriate scope:
    • READ for read-only applications
    • WRITE for applications that need to modify resources
    • ADMIN for administrative tools
  5. Optionally set an expiration date
  6. Copy and securely store the generated token

Token Security

The API token is only displayed once when created. Store it securely - you cannot retrieve it later. If lost, you'll need to create a new key.

Token Format

API keys follow this format:

zlk_live_<key_id>.<secret>

For example: zlk_live_abc123xyz.dGhpcyBpcyBhIHNlY3JldA

401 Unauthorized

Cause: Invalid, missing, or expired API key

json
{
  "type": "https://api.0.link/problems/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication required"
}

Solutions:

  • Verify the API key is included in the Authorization header
  • Check the key hasn't been revoked
  • Ensure proper formatting: Authorization: Bearer zlk_live_...

403 Forbidden

Cause: Valid key but insufficient scope for the operation

json
{
  "type": "https://api.0.link/problems/insufficient-scope",
  "title": "Forbidden",
  "status": 403,
  "detail": "This action requires WRITE scope"
}

Solutions:

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

Best Practices

Principle of Least Privilege

Grant the minimum scope needed for each use case:

javascript
// ✅ Good: Specific scope for each use case
const dashboardKey = {
  name: 'Domain Dashboard',
  scope: 'READ',  // Only needs to display data
};

const backendKey = {
  name: 'Backend Service',
  scope: 'WRITE',  // Needs to manage domains and DNS
};

// ❌ Avoid: Using ADMIN scope when not needed
const unnecessaryAdminKey = {
  name: 'Simple Display Widget',
  scope: 'ADMIN',  // Overly broad for just displaying data
};

Environment Separation

Use different API keys for each environment:

EnvironmentRecommended ScopeRationale
DevelopmentWRITEFull testing capabilities
StagingWRITEProduction-like testing
ProductionMinimum requiredSecurity best practice

Key Rotation

Regularly rotate API keys to maintain security:

  1. Create a new key with the same scope
  2. Update your applications to use the new key
  3. Verify the new key is working
  4. Revoke the old key

For programmatic rotation with a grace period:

graphql
mutation {
  rotateApiKey(
    keyId: "old_key_id",
    graceSeconds: 86400  # 24 hours for both keys to work
  ) {
    token
  }
}

Regular Security Reviews

  1. Audit existing keys: Remove unused keys
  2. Review scopes: Downgrade over-privileged keys
  3. Check last used dates: Identify potentially compromised keys
  4. Set expiration dates: Use validUntil for temporary access

Next Steps

Now that you understand API access:

  1. Explore the API Reference - See all available endpoints
  2. Interactive API Docs - Try the API with Swagger UI
  3. Learn About Authentication - Deep dive into security
  4. Choose an SDK - Use our official libraries

Getting Help

Questions about API access?