Owlbound API
Build on the Owlbound platform. Access contacts, intent signals, AI scoring, data enrichment, and company intelligence through a RESTful API. All endpoints are served under /api/v1 and return JSON.
Base URL
https://app.owlbound.ai/api/v1Content Type
Content-Type: application/jsonAuthentication
All API requests require a valid API key. Create and manage keys from the Developer tab in your Owlbound workspace.
Methods
X-API-Key headerrecommended
X-API-Key: gtm_sk_...Bearer token
Authorization: Bearer gtm_sk_...Key types
| Type | Prefix | Use case |
|---|---|---|
| Secret | gtm_sk_ | Server-side only. All scopes configurable. |
| Publishable | gtm_pk_ | Client-safe. Limited to signals:write. |
Example Request
curl https://app.owlbound.ai/api/v1/me \
-H "X-API-Key: gtm_sk_your_key_here"Scopes
Scopes control which resources a key can access. Secret keys can be configured with any combination. Publishable keys are restricted to signals:write only.
| Scope | Description |
|---|---|
| intelligence:read | AI-powered lead scoring and website analysis |
| enrichment:read | Contact and company data lookups |
| enrichment:write | Trigger enrichment jobs |
| messages:read | Read LinkedIn and email message threads |
| signals:read | Read intent signals |
| signals:write | Ingest intent signals from external sources |
| contacts:read | Read contact records and metadata |
| contacts:write | Create and update contact records |
| sequences:read | Read outreach sequences |
| sequences:write | Enroll contacts into sequences |
| workflows:read | Read signal workflows |
| workflows:write | Trigger signal workflows |
| connectors:read | Read connector health status |
| connectors:write | Manage connector instances |
Default Scopes by Key Type
// Secret keys include all scopes by default
{
"scopes": [
"intelligence:read",
"enrichment:read",
"enrichment:write",
"messages:read",
"signals:read",
"signals:write",
"contacts:read",
"contacts:write",
"sequences:read",
"sequences:write",
"workflows:read",
"workflows:write",
"connectors:read",
"connectors:write"
]
}Rate Limits
Rate limits are applied per API key using a sliding window. When exceeded, the API returns 429 Too Many Requests with a Retry-After header (in seconds).
| Plan | / min | / hour | / day |
|---|---|---|---|
| Starter | 60 | 1,000 | 10,000 |
| Pro | 120 | 5,000 | 50,000 |
| Enterprise | 300 | 15,000 | Unlimited |
Rate Limit Headers
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1705312200Capabilities & Credits
Use the capabilities endpoint to see each public API action, its required scope, and the credit cost recorded for successful calls. These successful calls are also mirrored into the workspace usage ledger with an api.* capability ID.
| Endpoint | Scope | Credits |
|---|---|---|
| POST /contacts | contacts:write | 1 |
| POST /workflows/:id/trigger | workflows:write | 2 |
| POST /sequences/:id/enroll | sequences:write | 3 |
| POST /contacts/:id/enrich | enrichment:write | 5 |
Capability inventory
curl https://app.owlbound.ai/api/v1/capabilitiesResponse Format
All responses use a consistent JSON envelope with a data key for successful requests and an error key for failures. Successful responses include a meta object with a unique request ID.
Response fields
| Field | Type | Description |
|---|---|---|
| data | object | Response payload (success only) |
| error | object | Error details with code and message (error only) |
| meta | object | Request metadata (requestId, credits) |
Success — 200
{
"data": {
"contacts": [ ... ]
},
"meta": {
"requestId": "req_abc123def456",
"credits": { "used": 1 }
}
}Error — 4xx / 5xx
{
"error": {
"code": "API_KEY_INVALID",
"message": "Invalid API key.",
"requestId": "req_abc123def456"
}
}Error Codes
When a request fails, the response includes an error object with a machine-readable code and a human-readable message.
| Code | Status | Description |
|---|---|---|
| MISSING_API_KEY | 401 | No API key was provided in the request. |
| API_KEY_INVALID | 401 | The API key provided is not valid. |
| API_KEY_EXPIRED | 401 | The API key has expired. |
| API_KEY_REVOKED | 401 | The API key has been revoked. |
| INSUFFICIENT_SCOPE | 403 | The key lacks the required scope for this endpoint. |
| VALIDATION_ERROR | 400 | Request validation failed. Check the details array. |
| RATE_LIMIT_EXCEEDED | 429 | Too many requests. Check the Retry-After header. |
| NOT_FOUND | 404 | The requested resource does not exist. |
| INTERNAL_ERROR | 500 | Unexpected server error. Contact support if persistent. |
/v1API root. Returns version information, available endpoints, and authentication details. Does not require authentication.
| Auth | None required |
| Scope | None required |
Response body
| Field | Type | Description |
|---|---|---|
| name | string | API name |
| version | string | Semantic version |
| endpoints | object | Map of available endpoints with path, method, scope |
| authentication | object | Supported auth methods and key format |
Request
curl https://app.owlbound.ai/api/v1Response
{
"name": "Owlbound API",
"version": "1.0.0",
"endpoints": {
"contacts.list": {
"path": "/api/v1/contacts",
"method": "GET",
"scope": "contacts:read"
},
...
},
"authentication": {
"methods": [
"X-API-Key header",
"Authorization: Bearer <key>"
],
"keyFormat": "gtm_sk_* (secret) or gtm_pk_* (publishable)"
}
}/v1/healthHealth check endpoint. Use this to monitor API availability from your infrastructure. Does not require authentication.
| Auth | None required |
| Scope | None required |
Response body
| Field | Type | Description |
|---|---|---|
| status | string | "operational" |
| timestamp | string | ISO 8601 timestamp |
| version | string | API version |
Request
curl https://app.owlbound.ai/api/v1/healthResponse
{
"status": "operational",
"timestamp": "2025-01-15T10:30:00Z",
"version": "1.0.0"
}/v1/meReturns information about the authenticated API key including workspace name, key type, granted scopes, and current rate limits. Useful for verifying key configuration.
| Auth | Required |
| Scope | contacts:read |
| Credits | 0 |
Response body
| Field | Type | Description |
|---|---|---|
| workspace.id | string | Workspace ID |
| workspace.name | string | Workspace name |
| workspace.plan | string | Current billing plan |
| workspace.status | string | Workspace status (e.g. "active") |
| apiKey.id | string | API key ID |
| apiKey.scopes | string[] | Granted scopes |
Request
curl https://app.owlbound.ai/api/v1/me \
-H "X-API-Key: gtm_sk_your_key_here"Response
{
"data": {
"workspace": {
"id": "k97f...",
"name": "Acme Corp",
"plan": "pro",
"status": "active"
},
"apiKey": {
"id": "j57d...",
"scopes": [
"intelligence:read",
"enrichment:read",
"enrichment:write",
"signals:read",
"signals:write",
"contacts:read",
"contacts:write"
]
}
},
"meta": {
"requestId": "req_abc123def456",
"credits": { "used": 0 }
}
}/v1/contactsReturns a paginated list of contacts in your workspace. Supports filtering by status, source, and company, with configurable sorting.
| Auth | Required |
| Scope | contacts:read |
| Credits | 1 |
Query parameters
| Param | Type | Description |
|---|---|---|
| limit | number | Results per page (max 100, default 50) |
| cursor | string | Pagination cursor from previous response |
| status | string | Filter: new, ready, contacted, replied, converted, lost |
| source | string | Filter: csv, linkedin, api, manual, etc. |
| company | string | Filter by company name (partial match) |
| sort_by | string | createdAt (default), score, activityScore |
| sort_direction | string | asc or desc (default) |
| include_archived | boolean | Include archived contacts (default false) |
curl "https://app.owlbound.ai/api/v1/contacts?status=new&limit=10" \
-H "X-API-Key: gtm_sk_your_key_here"{
"data": {
"contacts": [
{
"id": "k97f...",
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@acme.com",
"company": "Acme Corp",
"title": "VP Engineering",
"status": "new",
"score": 85,
"createdAt": 1705312200000
}
],
"hasMore": true,
"nextCursor": "k97f..."
},
"meta": { "requestId": "req_abc123", "credits": { "used": 1 } }
}/v1/contactsCreate a new contact in your workspace. At least one of firstName, lastName, email, or linkedInUrl is required. Duplicate detection runs on email and LinkedIn URL.
| Scope | contacts:write |
| Credits | 1 |
Request body
| Field | Type | Description |
|---|---|---|
| firstName | string? | First name |
| lastName | string? | Last name |
| string? | Email address (duplicate check) | |
| phone | string? | Phone number |
| linkedInUrl | string? | LinkedIn profile URL (duplicate check) |
| company | string? | Company name |
| title | string? | Job title |
| location | string? | City/region |
| source | string? | Origin (default: "api") |
| tags | string[]? | Tags array |
| notes | string? | Free-text notes |
curl -X POST https://app.owlbound.ai/api/v1/contacts \
-H "X-API-Key: gtm_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@acme.com",
"company": "Acme Corp",
"title": "VP Engineering"
}'{
"data": {
"contactId": "k97f..."
},
"meta": { "requestId": "req_abc123", "credits": { "used": 1 } }
}/v1/contacts/searchFull-text search across contacts. Searches name, title, company, email, and tags.
| Scope | contacts:read |
| Credits | 1 |
Request body
| Field | Type | Description |
|---|---|---|
| query | string | Search query (required) |
| limit | number? | Max results (default 25, max 100) |
| status | string? | Filter by status |
curl -X POST https://app.owlbound.ai/api/v1/contacts/search \
-H "X-API-Key: gtm_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "query": "VP Engineering", "limit": 10 }'/v1/contacts/:idGet a single contact by ID. Returns detailed contact information including enrichment data, scores, and connection status.
| Scope | contacts:read |
| Credits | 1 |
curl https://app.owlbound.ai/api/v1/contacts/k97f... \
-H "X-API-Key: gtm_sk_your_key_here"/v1/contacts/:idUpdate one or more fields on an existing contact. Only include fields you want to change.
| Scope | contacts:write |
| Credits | 1 |
curl -X PATCH https://app.owlbound.ai/api/v1/contacts/k97f... \
-H "X-API-Key: gtm_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "status": "contacted", "tags": ["priority", "enterprise"] }'/v1/contacts/:idArchive (soft-delete) a contact. The contact can be restored later from the dashboard. Optionally include a reason.
| Scope | contacts:write |
| Credits | 1 |
curl -X DELETE https://app.owlbound.ai/api/v1/contacts/k97f... \
-H "X-API-Key: gtm_sk_your_key_here"/v1/contacts/:id/enrichQueue a contact for data enrichment. The system will scrape LinkedIn profile data, find email/phone, analyze activity, check connection status, and score against ICP profiles. This is an asynchronous operation — poll GET /v1/enrichment/:contactId to check progress.
| Scope | enrichment:write |
| Credits | 5 |
Request body (optional)
| Field | Type | Description |
|---|---|---|
| priority | string? | critical, high (default), medium, low |
| forceRefresh | boolean? | Re-enrich even if data exists |
curl -X POST https://app.owlbound.ai/api/v1/contacts/k97f.../enrich \
-H "X-API-Key: gtm_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "priority": "high" }'/v1/enrichment/:contactIdCheck enrichment status for a contact. Returns current phase, completed phases, and any errors. Use this to poll for enrichment completion after calling POST /v1/contacts/:id/enrich.
| Scope | enrichment:read |
| Credits | 0 (free) |
curl https://app.owlbound.ai/api/v1/enrichment/k97f... \
-H "X-API-Key: gtm_sk_your_key_here"/v1/contacts/:id/scoreAI-score a contact against a specific ICP (Ideal Customer Profile). Returns a 0-100 score, verdict, breakdown by category, and reasoning. This is a synchronous operation that calls the AI model in real time.
| Scope | intelligence:read |
| Credits | 3 |
Request body
| Field | Type | Description |
|---|---|---|
| icpProfileId | string | ICP Profile ID to score against (required) |
curl -X POST https://app.owlbound.ai/api/v1/contacts/k97f.../score \
-H "X-API-Key: gtm_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "icpProfileId": "jd83..." }'/v1/signalsList combined intent and social signals. Returns a unified view of job changes, funding rounds, social posts, and other buying signals.
| Scope | signals:read |
| Credits | 1 |
Query parameters
| Param | Type | Description |
|---|---|---|
| type | string? | Filter by type: job_change, company_growth, funding_round, website_visit, content_download, job_posting, technology_adoption, custom_webhook |
| priority | string? | high, medium, low |
| limit | number? | Max results (default 50, max 100) |
| unactioned_only | boolean? | Only show unactioned signals |
curl "https://app.owlbound.ai/api/v1/signals?priority=high&limit=20" \
-H "X-API-Key: gtm_sk_your_key_here"/v1/signalsIngest an external intent signal. Use this to send buying signals from your own systems, webhooks, or third-party tools into the GTM platform. This endpoint works with publishable keys.
| Scope | signals:write |
| Credits | 1 |
Request body
| Field | Type | Description |
|---|---|---|
| type | string | Required. One of: job_change, company_growth, funding_round, website_visit, content_download, job_posting, technology_adoption, custom_webhook |
| data | object | Required. Signal-specific data (max 10KB) |
| contactId | string? | Link to existing contact |
| priority | string? | high, medium (default), low |
| source | string? | Source identifier (default: "api") |
| notes | string? | Free-text notes about the signal |
curl -X POST https://app.owlbound.ai/api/v1/signals \
-H "X-API-Key: gtm_pk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"type": "website_visit",
"data": {
"pageUrl": "/pricing",
"referrer": "https://google.com",
"company": { "name": "Acme Corp", "domain": "acme.com" }
},
"priority": "high",
"source": "website_tracker"
}'/v1/signals/statsGet signal statistics by type and priority for a given time range. Useful for dashboards and reporting.
| Scope | signals:read |
| Credits | 0 (free) |
Query parameters
| time_range | string? | day, week (default), month |
curl "https://app.owlbound.ai/api/v1/signals/stats?time_range=week" \
-H "X-API-Key: gtm_sk_your_key_here"/v1/companiesList companies in your workspace with optional industry filter and pagination.
| Scope | contacts:read |
| Credits | 1 |
Query parameters
| limit | number? | Max results (default 25, max 50) |
| industry | string? | Filter by industry |
| cursor | string? | Pagination cursor |
curl "https://app.owlbound.ai/api/v1/companies?industry=SaaS&limit=10" \
-H "X-API-Key: gtm_sk_your_key_here"/v1/companiesCreate or update a company by LinkedIn URL. Existing non-empty fields are preserved so enrichment and CRM data are not overwritten accidentally.
| Scope | contacts:write |
| Required | linkedInUrl |
curl https://app.owlbound.ai/api/v1/companies \
-H "X-API-Key: gtm_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"linkedInUrl": "https://www.linkedin.com/company/acme",
"name": "Acme Corp",
"domain": "acme.com",
"industry": "SaaS"
}'/v1/companies/:idGet a single company by ID with full details and contact count.
| Scope | contacts:read |
| Credits | 1 |
curl https://app.owlbound.ai/api/v1/companies/p12f... \
-H "X-API-Key: gtm_sk_your_key_here"/v1/sequences/:id/enrollEnroll a contact into an active outreach sequence. The API checks workspace ownership, exclusion rules, archived status, duplicate active enrollments, and sequence steps.
| Scope | sequences:write |
| Body | contactId, source? |
curl https://app.owlbound.ai/api/v1/sequences/seq123/enroll \
-H "X-API-Key: gtm_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "contactId": "contact123", "source": "api" }'/v1/workflows/:id/triggerTrigger an active signal workflow for a contact by creating a custom webhook signal and routing it through the signal router.
| Scope | workflows:write |
| Body | contactId, data? |
curl https://app.owlbound.ai/api/v1/workflows/wf123/trigger \
-H "X-API-Key: gtm_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{ "contactId": "contact123", "data": { "source": "webhook" } }'/v1/connectorsList connector instances with redacted configuration and computed health. Use it to power connector dashboards, external monitoring, and agent audits.
| Scope | connectors:read |
| Filters | integrationSlug?, includeArchived? |
curl "https://app.owlbound.ai/api/v1/connectors?integrationSlug=slack" \
-H "X-API-Key: gtm_sk_your_key_here"/v1/connectors/:idGet one connector with its redacted setup and latest computed health status.
| Scope | connectors:read |
curl https://app.owlbound.ai/api/v1/connectors/conn123 \
-H "X-API-Key: gtm_sk_your_key_here"Best Practices
Keep secret keys secure
Rotate keys regularly
Handle errors and retries
Respect rate limits
Start building on Owlbound
Create an API key and integrate contacts, signals, and AI scoring into your workflow.