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.