API Concepts

Understand the architecture, authentication, and core resources

API Architecture Overview

WEIR provides two distinct API surfaces designed for different use cases:

External API

For third-party developers building integrations.

https://wapi.weir.ai/

  • Read access to public licenses
  • Full CRUD on owned resources
  • Webhook subscriptions

Internal API

For first-party WEIR applications.

https://id.weir.ai/api-v2/internal/v2/

  • User authentication methods
  • Profile & settings management
  • Claims & earnings access

Core Domain Concepts

Identities

People whose likeness can be licensed. Identities have legal names (private), display/stage names (public), verification status, and reference images for detection.

Licenses

Rights packages defining how an identity can be used. Each license specifies terms, restrictions, pricing, and status (draft, private, public, archived). Licenses are the primary resource in the API.

Mentions

Discovered content that may reference a licensed identity. Found through text matching (name detection) or image matching (visual identity detection). Mentions have confidence scores and statuses: pending, confirmed, rejected, or flagged.

Webhooks

Real-time notifications when events occur: license.created, license.published, mention.detected, subscription.started, and more. Configure endpoints to receive HMAC-signed payloads.

Authentication Model

API Key Types

Domain Keys

weir_domain_

For server-to-server and web applications.

  • • Optional domain restriction
  • • No bundle ID required
  • • Higher rate limits available

App Keys

weir_app_

For iOS and Android applications.

  • • Bundle ID binding required
  • • Admin verification required
  • • X-Bundle-ID header required

Token Lifecycle

Exchange

API Key + Secret

Access Token

1 hour lifetime

Refresh Token

30 day lifetime

Scopes

license:read — View licenses

license:write — Create/update

mention:read — View mentions

mention:write — Manage mentions

webhook:manage — Manage webhooks

user:read — View profile

Legacy plural forms (e.g., licenses:read) are still supported for backward compatibility.

Response Format

All API responses use a consistent light envelope pattern:

SuccessError

{
  "success": true,
  "data": { ... },
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "totalItems": 150,
    "totalPages": 8,
    "hasMore": true
  }
}

Every response includes an X-Request-ID header. Include this when contacting support for faster issue resolution.

Rate Limiting

Key Type Limit Burst
Domain Key 1,000/hour 100/minute
App Key 500/hour 50/minute
Public Metadata 60/minute 10/second

Responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.

Token Security

Proper token storage is critical for application security. Different tokens have different sensitivity levels and storage requirements.

Token Classification

Token Sensitivity Storage Requirement
API Key High (static) Secure backend only
API Secret Critical Backend only, encrypted at rest
Access Token Medium (1hr) Secure memory or encrypted storage
Refresh Token High (30 days) Must be stored securely

Mobile Storage Best Practices

iOS

iOS Keychain Services

Use kSecAttrAccessibleWhenUnlockedThisDeviceOnly for refresh tokens:

import Security

func storeRefreshToken(_ token: String) {
    let data = token.data(using: .utf8)!
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: "weir_refresh_token",
        kSecAttrService as String: "com.yourapp.weir",
        kSecValueData as String: data,
        kSecAttrAccessible as String:
            kSecAttrAccessibleWhenUnlockedThisDeviceOnly
    ]
    SecItemDelete(query as CFDictionary)
    SecItemAdd(query as CFDictionary, nil)
}

Security Best Practices

Never ship API secrets in mobile apps—use backend token exchange

Clear tokens on logout from all secure storage

Refresh proactively—refresh tokens ~5 minutes before expiration

Handle 401 gracefully—prompt re-authentication when tokens are revoked

Use certificate pinning in mobile apps to prevent MITM attacks

Token Compatibility

Internal and External API tokens are not interchangeable. Each API surface has its own token type with different capabilities and storage mechanisms.

Question Answer
Can I use an Internal token on External API? No
Internal tokens are stored in weir_api_access_tokens and issued via passkey/magic-link/password. External API only accepts tokens from weir_api_tokens.
Can I use an External token on Internal API? No
External tokens have limited scopes (license:read, mention:read, webhook:manage) and cannot access internal endpoints like /profile, /claims, /earnings.
Can I use a Supabase JWT directly? Internal API Only
The Internal API accepts Supabase JWTs via token exchange and direct validation. The External API does not accept Supabase JWTs.
Why are they separate? Security isolation. Internal API is for first-party apps with full user context; External API is for third-party integrations with restricted scopes.

Token Flow Diagram

┌───────────────────────────────────────────────────────────────┐
│                     TOKEN COMPATIBILITY                        │
├───────────────────────────────────────────────────────────────┤
│                                                               │
│   INTERNAL TOKENS                    EXTERNAL TOKENS          │
│   (weir_api_access_tokens)           (weir_api_tokens)        │
│   ┌─────────────────────┐           ┌──────────────────┐      │
│   │ Issued via:         │           │ Issued via:      │      │
│   │ • Passkey           │           │ • API key +      │      │
│   │ • Magic Link        │           │   secret         │      │
│   │ • Password          │           │                  │      │
│   │ • Supabase JWT      │           │                  │      │
│   └─────────────────────┘           └──────────────────┘      │
│            │                               │                  │
│            ▼                               ▼                  │
│   ┌─────────────────────┐           ┌──────────────────┐      │
│   │ INTERNAL API        │    ✗      │ EXTERNAL API     │      │
│   │ /internal/v2/...    │ ◄─────────│ /v2/...          │      │
│   │                     │           │                  │      │
│   │ Full access:        │    ✗      │ Limited scopes:  │      │
│   │ • profile           │ ─────────►│ • license:read   │      │
│   │ • claims            │           │ • mention:read   │      │
│   │ • earnings          │           │ • webhook:manage │      │
│   │ • settings          │           │                  │      │
│   └─────────────────────┘           └──────────────────┘      │
│                                                               │
│   ✗ = Token type NOT accepted on this API                     │
└───────────────────────────────────────────────────────────────┘

If you're building a third-party integration, use the External API with domain/app keys. If you're building a WEIR mobile app or first-party client, use the Internal API with service tokens.