API Reference
The ExtractVibe API lets you extract comprehensive brand kits from any website programmatically. All endpoints are served from https://extractvibe.com/api.
Base URL
https://extractvibe.com/apiQuick start
Extract a brand kit in three steps: start an extraction, poll for completion, then fetch the result.
# 1. Start extraction
JOB=$(curl -s -X POST https://extractvibe.com/api/extract \
-H "Content-Type: application/json" \
-H "x-api-key: ev_your_api_key_here" \
-d '{"url": "https://stripe.com"}')
JOB_ID=$(echo $JOB | jq -r '.jobId')
# 2. Poll until complete (typically 15-25 seconds)
curl -s https://extractvibe.com/api/extract/$JOB_ID \
-H "x-api-key: ev_your_api_key_here"
# 3. Get the brand kit
curl -s https://extractvibe.com/api/extract/$JOB_ID/result \
-H "x-api-key: ev_your_api_key_here" | jq .Authentication
ExtractVibe supports two authentication methods: session cookies and API keys. Session cookies are set automatically when you sign in through the web interface. API keys are designed for programmatic access and server-to-server integrations.
To authenticate with an API key, include it in the `x-api-key` header of your request. API keys use the `ev_` prefix and can be created and managed from your dashboard or via the API keys endpoints.
Some endpoints work without authentication (marked as "optional" or "none"). Anonymous requests are subject to stricter rate limits. Authenticated requests receive higher limits based on your plan tier.
Never expose your API key in client-side code. Use environment variables on your server and proxy requests if you need to call the API from a browser.
Session cookie
# Session cookies are set automatically after sign-in.
# Include credentials in browser requests:
fetch("/api/credits", { credentials: "include" });API key
curl https://extractvibe.com/api/credits \
-H "x-api-key: ev_your_api_key_here"Rate Limits
All endpoints are rate limited. Limits vary by authentication tier. Rate limit information is included in response headers: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset.
| Tier | Reads | Writes | Window |
|---|---|---|---|
| Anonymous | 30 req/min | 3 req/day | 60s / 24h |
| Free | 60 req/min | 10 req/min | 60s |
| Starter | 180 req/min | 30 req/min | 60s |
| Pro | 600 req/min | 60 req/min | 60s |
Error Codes
The API uses standard HTTP status codes. All error responses include a JSON body with an error field describing the problem.
| Status | Name | Description |
|---|---|---|
| 400 | Bad Request | The request body is malformed or missing required fields. Check the endpoint documentation for required parameters. |
| 401 | Unauthorized | Authentication is required but was not provided, or the provided credentials are invalid. |
| 402 | Payment Required | Your credit balance is zero. Upgrade your plan or wait for the monthly reset. |
| 404 | Not Found | The requested resource does not exist. The job ID, API key, or brand domain was not found. |
| 429 | Too Many Requests | You have exceeded the rate limit for your tier. Check the X-RateLimit-Reset header for when you can retry. |
| 500 | Internal Server Error | An unexpected error occurred. If this persists, please open an issue on GitHub. |
Error response format
{
"error": "Rate limit exceeded",
"limit": 30,
"retryAfter": 45
}Endpoints
Complete reference for all 12 API endpoints. Each endpoint includes authentication requirements, rate limits, request/response schemas, and code examples in cURL, JavaScript, and Python.
/api/healthHealth check
Returns the API status, version, and current timestamp. Use this to verify connectivity before making other calls.
Responses
{
"ok": true,
"version": "0.1.0",
"timestamp": 1742342400000
}Examples
curl https://extractvibe.com/api/health/api/extractStart extraction
Starts a brand extraction job for the given URL. Returns a job ID that you can use to poll for status and retrieve results. Each extraction costs 1 credit for authenticated users. Anonymous users get 3 free extractions per day.
Request body
JSON object with a `url` field. The URL can include or omit the protocol -- `https://` will be prepended automatically if missing.
{
"url": "https://stripe.com"
}Responses
{
"jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"domain": "stripe.com"
}{
"error": "Missing required field: url"
}{
"error": "No credits remaining. Upgrade your plan or wait for monthly reset."
}{
"error": "Rate limit exceeded",
"limit": 3,
"retryAfter": 72000
}Examples
curl -X POST https://extractvibe.com/api/extract \
-H "Content-Type: application/json" \
-H "x-api-key: ev_your_api_key_here" \
-d '{"url": "https://stripe.com"}'/api/extract/:jobIdPoll job status
Check the current status of an extraction job. The status field will be one of: `queued`, `running`, `complete`, or `errored`. Anyone with the job ID can poll status.
Path parameters
| jobId | The UUID returned from POST /api/extract |
Responses
{
"jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": {
"status": "running",
"error": null,
"output": null
}
}{
"jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": {
"status": "complete",
"error": null,
"output": {
"domain": "stripe.com",
"cached": true
}
}
}{
"error": "Job not found"
}Examples
curl https://extractvibe.com/api/extract/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "x-api-key: ev_your_api_key_here"/api/extract/:jobId/resultGet extraction result
Retrieve the full brand kit result for a completed extraction job. Returns the complete brand analysis including colors, typography, voice, personality, and rules. Results are cached in KV for fast retrieval.
Path parameters
| jobId | The UUID returned from POST /api/extract |
Responses
{
"meta": {
"domain": "stripe.com",
"url": "https://stripe.com",
"extractedAt": "2026-03-18T12:00:00Z",
"durationMs": 18420,
"schemaVersion": "v1"
},
"colors": {
"primary": "#635BFF",
"secondary": "#0A2540",
"accent": "#00D4AA",
"background": "#FFFFFF",
"palette": [
{
"hex": "#635BFF",
"role": "primary",
"name": "Stripe Purple"
},
{
"hex": "#0A2540",
"role": "secondary",
"name": "Ink"
},
{
"hex": "#00D4AA",
"role": "accent",
"name": "Cyan"
},
{
"hex": "#425466",
"role": "muted",
"name": "Slate"
},
{
"hex": "#F6F9FC",
"role": "background",
"name": "Off White"
}
]
},
"typography": {
"headings": {
"family": "Sohne",
"weight": "600",
"style": "normal"
},
"body": {
"family": "Sohne",
"weight": "400",
"style": "normal"
},
"mono": {
"family": "Sohne Mono",
"weight": "400",
"style": "normal"
},
"scale": [
14,
16,
20,
24,
32,
48,
64
]
},
"voice": {
"tone": "confident, technical, approachable",
"personality": [
"innovative",
"reliable",
"developer-friendly"
],
"writingStyle": "Clear and concise with technical precision. Uses active voice and addresses the reader directly.",
"samplePhrases": [
"Financial infrastructure for the internet",
"Start building with Stripe",
"Payments built for developers"
]
},
"logos": [
{
"url": "https://extractvibe-assets.r2.dev/stripe.com/logo-primary.svg",
"type": "svg",
"variant": "primary",
"width": 120,
"height": 50
}
],
"vibeScore": 92,
"tags": [
"premium",
"developer-first",
"polished",
"enterprise"
]
}{
"error": "Result not found or still processing"
}Examples
curl https://extractvibe.com/api/extract/a1b2c3d4-e5f6-7890-abcd-ef1234567890/result \
-H "x-api-key: ev_your_api_key_here"/api/brand/:domainGet brand by domain
Retrieve a cached brand kit by domain name. This is a public endpoint that returns the most recent extraction result for a given domain. If the domain has not been extracted yet, returns 404.
Path parameters
| domain | The domain name without protocol or www prefix (e.g., `stripe.com`) |
Responses
{
"meta": {
"domain": "stripe.com",
"url": "https://stripe.com",
"extractedAt": "2026-03-18T12:00:00Z",
"durationMs": 18420,
"schemaVersion": "v1"
},
"colors": {
"primary": "#635BFF",
"secondary": "#0A2540",
"accent": "#00D4AA",
"background": "#FFFFFF",
"palette": [
{
"hex": "#635BFF",
"role": "primary",
"name": "Stripe Purple"
}
]
},
"typography": {
"headings": {
"family": "Sohne",
"weight": "600"
},
"body": {
"family": "Sohne",
"weight": "400"
}
},
"voice": {
"tone": "confident, technical, approachable",
"personality": [
"innovative",
"reliable",
"developer-friendly"
]
},
"vibeScore": 92,
"tags": [
"premium",
"developer-first",
"polished"
]
}{
"error": "Brand not found. Extract it first."
}Examples
curl https://extractvibe.com/api/brand/stripe.com/api/extract/historyList extraction history
Returns the 50 most recent extraction jobs for the authenticated user, ordered by creation date descending. Each entry includes the job ID, domain, status, and timing information.
Responses
{
"extractions": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"domain": "stripe.com",
"url": "https://stripe.com",
"status": "complete",
"durationMs": 18420,
"createdAt": "2026-03-18T12:00:00Z",
"completedAt": "2026-03-18T12:00:18Z"
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"domain": "linear.app",
"url": "https://linear.app",
"status": "complete",
"durationMs": 15230,
"createdAt": "2026-03-17T09:30:00Z",
"completedAt": "2026-03-17T09:30:15Z"
}
]
}{
"error": "Unauthorized"
}Examples
curl https://extractvibe.com/api/extract/history \
-H "x-api-key: ev_your_api_key_here"/api/extract/:jobId/export/:formatExport brand kit
Download a brand kit in various formats. Supported formats: `json` (full brand kit), `css` (CSS custom properties), `tailwind` (Tailwind CSS theme), `markdown` (human-readable report), and `tokens` (W3C design tokens). Returns the file as a download attachment.
Path parameters
| jobId | The UUID of a completed extraction job |
| format | Export format: `json`, `css`, `tailwind`, `markdown`, or `tokens` |
Responses
/* stripe.com — extracted by ExtractVibe */
:root {
--brand-primary: #635BFF;
--brand-secondary: #0A2540;
--brand-accent: #00D4AA;
--brand-background: #FFFFFF;
--brand-muted: #425466;
--font-heading: "Sohne", sans-serif;
--font-body: "Sohne", sans-serif;
--font-mono: "Sohne Mono", monospace;
}{
"error": "Invalid format. Use: json, css, tailwind, markdown, tokens"
}{
"error": "Result not found"
}Examples
# Download as CSS variables
curl -o stripe-variables.css \
https://extractvibe.com/api/extract/a1b2c3d4-e5f6-7890-abcd-ef1234567890/export/css \
-H "x-api-key: ev_your_api_key_here"
# Download as Tailwind theme
curl -o stripe-tailwind.css \
https://extractvibe.com/api/extract/a1b2c3d4-e5f6-7890-abcd-ef1234567890/export/tailwind \
-H "x-api-key: ev_your_api_key_here"/api/creditsGet credit balance
Returns the current credit balance and plan for the authenticated user. Free accounts start with 50 credits that reset monthly.
Responses
{
"credits": 47,
"plan": "free"
}{
"error": "Unauthorized"
}Examples
curl https://extractvibe.com/api/credits \
-H "x-api-key: ev_your_api_key_here"/api/keysCreate API key
Creates a new API key for the authenticated user. The full key is returned only once in the response -- store it securely. Keys use the `ev_` prefix followed by 48 hex characters.
Request body
Optional JSON object with a `name` field for the key. Defaults to "Default" if omitted.
{
"name": "Production server"
}Responses
{
"id": "c3d4e5f6-a7b8-9012-cdef-234567890123",
"name": "Production server",
"key": "ev_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4"
}{
"error": "Unauthorized"
}Examples
curl -X POST https://extractvibe.com/api/keys \
-H "Content-Type: application/json" \
-H "x-api-key: ev_your_existing_key" \
-d '{"name": "Production server"}'/api/keysList API keys
Returns all active API keys for the authenticated user. Keys are listed by creation date descending. The full key value is not returned -- only the ID, name, and timestamps.
Responses
{
"keys": [
{
"id": "c3d4e5f6-a7b8-9012-cdef-234567890123",
"name": "Production server",
"createdAt": "2026-03-15T10:00:00Z",
"lastUsedAt": "2026-03-18T14:30:00Z"
},
{
"id": "d4e5f6a7-b8c9-0123-defa-345678901234",
"name": "Development",
"createdAt": "2026-03-10T08:00:00Z",
"lastUsedAt": null
}
]
}{
"error": "Unauthorized"
}Examples
curl https://extractvibe.com/api/keys \
-H "x-api-key: ev_your_api_key_here"/api/keys/:idRevoke API key
Permanently deletes an API key. The key will immediately stop working for any requests. This action cannot be undone.
Path parameters
| id | The UUID of the API key to revoke |
Responses
{
"ok": true
}{
"error": "Key not found"
}{
"error": "Unauthorized"
}Examples
curl -X DELETE https://extractvibe.com/api/keys/c3d4e5f6-a7b8-9012-cdef-234567890123 \
-H "x-api-key: ev_your_api_key_here"/api/openapi.jsonOpenAPI specification
Returns the OpenAPI 3.1 specification for the ExtractVibe API. Use this to generate client libraries, import into Postman, or integrate with any OpenAPI-compatible tooling.
Responses
{
"openapi": "3.1.0",
"info": {
"title": "ExtractVibe API",
"version": "0.1.0",
"description": "Brand intelligence extraction API"
},
"servers": [
{
"url": "https://extractvibe.com"
}
],
"paths": {
"...": "Full endpoint definitions"
}
}Examples
# Download the OpenAPI spec
curl -o openapi.json https://extractvibe.com/api/openapi.json
# Import into Postman or generate a client
npx openapi-typescript openapi.json -o types.ts