API reference
REST API reference
Base URL: https://api.lumensieve.com · All endpoints require a Bearer token · All bodies and responses are JSON.
Prefer a machine-readable spec (e.g. for codegen, or pointing an AI coding assistant at it)? The full OpenAPI 3.0 spec (also at /openapi.json) is served directly by the API itself, so it never drifts from what's actually deployed.
Profiles
/v1/profiles/lookupKick off a business profile resolve — by name + country, or by domain alone when you already know the business's website. Requires the profiles:write scope. This is asynchronous — a cold full resolve runs the complete discovery → crawl → extraction → reconciliation pipeline and typically takes a few minutes (a preview resolve returns fast partial data in a few seconds), so this endpoint returns immediately and you poll for the result (see below).
Request body
| Field | Type | Required | Description |
|---|---|---|---|
businessName | string | Conditional | Company name — required unless domain is given. |
countryHint | string | Conditional | ISO 3166-1 alpha-2 country code — required when businessName is given |
domain | string | Conditional | The business’s website domain (e.g. "acmecoffee.com") — an alternative to businessName + countryHint. See "Lookup by domain" below. |
mode | "preview" | "full" | — | preview = fast partial data; full = complete profile (default: full) |
localityHint | string | Conditional | State, province, or city — required when countryHint is a federated country (see below); never required for a domain lookup |
force_refresh | boolean | — | Bypass the cached profile (if any) and run a fresh resolve |
Federated countries require a locality hint. For US, IN, BR, CA, AU, DE, MX, and NG, business names commonly repeat across many distinct, unrelated locations (a "Joe's Pizza" in a dozen different states) — name + country alone isn't enough to reliably identify one. Omitting localityHint for these countries returns MISSING_REQUIRED_FIELD; supplying one that isn't a real state, province, or city in that country returns INVALID_FIELD_VALUE. This requirement never applies to a domain lookup — a domain is inherently unambiguous.
Request body (by name + country)
{
"businessName": "Blispa Barbershop & Spa",
"countryHint": "KE",
"mode": "full"
}Request body (by domain)
No countryHint or localityHint needed — the engine deep-crawls the given domain first, extracts the business's real name and every fingerprint (phone, email, address, social links) directly from the site, and derives the country from the domain itself (its country-code TLD, or a phone number found on the site) before the rest of the resolve runs. This is often a cleaner match than name + country: you've already supplied an unambiguous anchor, so there's no name to disambiguate.
{
"domain": "artcaffe.co.ke",
"mode": "full"
}Response — 202 Accepted
{
"businessId": "616de6d1-7732-4ece-a551-5e3187923aa8",
"pollUrl": "/v1/profiles/616de6d1-7732-4ece-a551-5e3187923aa8",
"status": "processing"
}Poll pollUrl (i.e. GET /v1/profiles/{businessId}) every few seconds until it stops returning 202. See that endpoint below for the shape of the finished result.
/v1/profiles/{id}Poll for a resolve's result, or re-fetch an already-completed profile by its business ID — the same ID returned by POST /v1/profiles/lookup. Requires profiles:read.
Query parameters
| Parameter | Type | Description |
|---|---|---|
include_attributions | boolean | Include per-field source attribution in the response |
Response by state
| HTTP status | Meaning |
|---|---|
202 | Still resolving — { "businessId": "…", "status": "processing" }. Poll again shortly. |
200 | Resolve finished — { "profile": { /* see Data model */ }, "profileId": "…" } |
500 | Resolve finished but failed — { "error": { "code": "INTERNAL_ERROR", "message": "…" } } |
/v1/profiles/{id}/refreshForce a full re-generation of a profile, bypassing all caches. Counts against your lookup quota.
/v1/profiles/{id}/correctionsSubmit a data correction for a specific field. Corrections are reviewed and applied to future profile generations.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
field_path | string | ✓ | Dot-path of the field to correct (e.g. "contact.website") |
correct_value | any | ✓ | The correct value as JSON |
explanation | string | — | Optional human-readable explanation |
/v1/profiles/{id}/attribution/{fieldPath}Return per-field source attribution — which sources contributed to a specific field and at what confidence.
Not yet available in production — this currently returns 501 NOT_IMPLEMENTED. Every field in the main profile response already carries its own metadata.sources and metadata.confidence inline (see Data model), which covers most attribution needs today.
/v1/profiles/{id}/askAsk a natural language question about a profile. Requires the ask_lumen feature on your plan.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
question | string | ✓ | Natural language question, max 1000 characters |
conversation_history | string[] | — | Previous turns for multi-turn conversations |
/v1/profiles/lookup/streamStream profile generation as Server-Sent Events. Each event is a JSON object. The stream ends with an event: done sentinel.
Event types
| type | Description |
|---|---|
source_discovered | A data source URL was found |
source_completed | A source finished extraction |
section_completed | A profile section (e.g. contact) is ready |
partial_profile | Preview-quality partial profile available |
complete | Full profile is ready |
error | A non-fatal error occurred |
/v1/profilesList profiles in the account, paginated.
Query parameters
| Parameter | Type | Description |
|---|---|---|
cursor | string | Pagination cursor from a previous response |
limit | number | Items per page (default 20, max 100) |
q | string | Filter by name or domain |
Lookup notifications
Get called back when a lookup finishes instead of polling — see Lookup notifications for the full guide (payload shape, signature verification). Requires webhooks:manage. Covers only profile.resolved / profile.failed — not a general eventing system.
/v1/webhooks/subscriptionsRegister a URL to be called when a lookup you started resolves or fails.
/v1/webhooks/subscriptionsList your registered URLs.
/v1/webhooks/subscriptions/{id}Remove a registered URL.
/v1/webhooks/deliveriesList recent delivery attempts across your subscriptions.
/v1/webhooks/deliveries/{id}Inspect one delivery attempt.
/v1/webhooks/deliveries/{id}/retryManually retry one delivery.
/v1/webhooks/dead-letterList deliveries that exhausted all automatic retries.
/v1/webhooks/dead-letter/{id}/replayRe-attempt a dead-lettered delivery.
/v1/webhooks/testSend a synthetic test event to a URL before relying on it.
Billing
/v1/billing/portalCreate a short-lived Creem customer portal session. Redirect the customer to overview_url to manage their payment method or cancel — both are handled on Creem's own hosted pages, and Creem's webhook syncs any resulting change back to your account.
Response
{
"overview_url": "https://www.creem.io/my-orders/..."
}cancel_url and update_payment_method_url may also appear in this object, but Creem's portal is a single page rather than separate deep links, so in practice they are omitted — send the customer to overview_url and let them navigate from there.
/v1/billing/invoicesList the account's billing/invoice history.
/v1/billing/invoices/{id}/pdfGet a short-lived (~1 hour) signed PDF URL for one invoice.
Usage & account
/v1/usageFull usage metrics for the current billing period, including per-resource used/limit/remaining.
/v1/usage/summaryCondensed summary view matching the dashboard's usage page.
/v1/usage/timeseriesDaily usage breakdown for the current billing period.
/v1/accountAccount details including tier, features enabled, and support info.
/v1/account/keysCreate a new API key. The rawKey in the response is shown exactly once.
/v1/account/keysList all active API keys (raw keys are never returned — only metadata).
/v1/account/keys/{id}Revoke an API key immediately. Requests using the revoked key fail within 60 seconds.
Health checks
/healthLiveness check. Returns 200 OK if the gateway process is running. No auth required.
/readyReadiness check. Returns 200 OK when all downstream services are reachable. No auth required.
