Core Concepts
Understand how Orsa works under the hood.
Brand Data Model
When you call /v1/brand/retrieve, Orsa returns a comprehensive brand profile:
{
"name": "Stripe",
"domain": "stripe.com",
"description": "Financial infrastructure for the internet.",
"logos": [
{ "url": "https://...", "type": "svg", "theme": "light" },
{ "url": "https://...", "type": "png", "theme": "dark" }
],
"colors": ["#635BFF", "#0A2540", "#00D4AA"],
"fonts": ["Inter", "system-ui"],
"industry": "Financial Technology",
"naics_code": "522320",
"socials": {
"twitter": "https://twitter.com/stripe",
"linkedin": "https://linkedin.com/company/stripe",
"github": "https://github.com/stripe"
},
"meta": {
"title": "Stripe | Payment Processing Platform",
"description": "...",
"favicon": "https://stripe.com/favicon.ico"
}
}How It Works
- Fetch — Orsa loads the target domain using a headless browser
- Extract — Multiple extractors run in parallel: logos, colors, fonts, social links, metadata, industry classification
- Assemble — Results are merged, deduplicated, and scored for confidence
- Cache — The assembled profile is cached for fast subsequent lookups
Caching
Orsa uses a two-tier cache for performance:
| Tier | Latency | TTL | Description |
|---|---|---|---|
| Warm cache (Redis) | ~250ms | 24 hours | Recent lookups served instantly |
| Cold fetch (Browser) | 5–10s | — | First-time or expired domains require a live fetch |
- Cached responses are free (0 credits).
- You can force a fresh fetch by passing
?refresh=true(costs normal credits).
Credits
Every API call costs a specific number of credits based on the endpoint and computational cost:
| Endpoint | Credits | Description |
|---|---|---|
/v1/web/scrape/html | 1 | Raw HTML extraction |
/v1/web/scrape/markdown | 2 | HTML → clean Markdown |
/v1/brand/retrieve | 5 | Full brand profile |
/v1/brand/screenshot | 5 | Pixel-perfect screenshot |
/v1/brand/ai/query | 10 | AI-powered extraction |
/v1/web/crawl | 50+ | Full site crawl (varies by pages) |
Credit Tracking
- Check your balance anytime via the dashboard (opens in a new tab) or the
/v1/healthendpoint - Set up credit alerts in Settings to get notified at 10% remaining
- Credits reset monthly on your billing date
- Unused credits do not roll over
Rate Limits
| Plan | Rate Limit |
|---|---|
| Free | 30 requests/min |
| Pro | 600 requests/min |
| Enterprise | Custom |
When you hit a rate limit, the API returns 429 Too Many Requests with a Retry-After header indicating seconds to wait.
Error Handling
All errors follow a consistent format:
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 2 seconds.",
"status": 429
}
}Common error codes:
| Code | Status | Meaning |
|---|---|---|
UNAUTHORIZED | 401 | Invalid or missing API key |
INSUFFICIENT_CREDITS | 402 | Not enough credits |
RATE_LIMIT_EXCEEDED | 429 | Too many requests |
DOMAIN_UNREACHABLE | 422 | Target domain couldn't be loaded |
INTERNAL_ERROR | 500 | Something went wrong on our end |