Browse the docs

Reference · 10 operations

Actions: enrich, score, AI and research

Last updated from API version 2026-10-06 at (live spec, refreshed hourly). openapi.json

Score

actions.score.contact

Score a contact against an ICP with AI.

post/api/v1/actions/score/contact
Scope
enrich
Credits
14 credits per target
Idempotency-Key
required
Class
spend
Approval floor
none
Runs
Inline for one target, else async
Targets
contact, contacts
Max targets
1,000
Dry run
Supported
Writes back
contact

Spend class. Scores each contact against an ICP with AI (the workspace's ICP criteria, psychology and scoring prompt, as the app does) and writes the score, verdict and reasoning onto the contact with a contact_scored signal. ICP: input.icpProfileId (this workspace's, else 404), else the contact's own (none: skipped NO_ICP). A contact with nothing to match on (no job title with a company or industry, no enrichment data) is skipped NOT_ENRICHED and holds nothing; when every target is, the request is 422 NOT_ENRICHED (never a silent 0 score). An ICP without a scoring configuration fails SCORING_NOT_CONFIGURED (free). 14 credits (scoring.contact.single) per scored contact, charged once by the action: the scorer's own debit is skipped (billing: caller). One target runs inline (200 {data: {action, result}}, its price held then settled); more (or mode: "async") create an async run (202), billed per batch of 25. dryRun: true returns the plan and calls nothing.

Parameters

  • Idempotency-Keyheaderstring

    1 to 255 printable ASCII characters, scoped to the API key (a rotated key shares its predecessor's keys) and kept 24 h. Accepted on every POST, PATCH and DELETE (ignored on GET); required from v1 keys where the operation says x-owlbound-idempotent: required (missing: 400 VALIDATION_ERROR, param: Idempotency-Key). Same key and body after completion: the stored response is replayed with Idempotent-Replayed: true. Results over 64 KB are not stored; their replay is 409 IDEMPOTENCY_RESULT_UNAVAILABLE with details.originalRequestId (check state with a GET). Same key while the first request runs: 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Same key, other body or operation: 422 IDEMPOTENCY_KEY_REUSED. A request that ended 5xx may be retried with the same key. 4xx results are stored and replayed too: a 402 INSUFFICIENT_CREDITS replays even after a top-up, so use a new Idempotency-Key after adding credits.

    min length 1max length 255
  • Owlbound-Dry-Runheaderboolean

    true: same as body field dryRun: true (action operations).

  • Owlbound-Planheaderstring

    A planId from a dry run: same as the body field planId (action operations). A different body planId is 400.

    pattern ^plan_[0-9a-f]{48}$

Request body (required) · application/json

ScoreContactRequest

  • targetone ofrequired
    0
    + Show child fields
  • 0
  • dryRunboolean

    Same as the Owlbound-Dry-Run header.

    0
  • planIdstring

    Apply this dry run's plan (same as Owlbound-Plan). Not with dryRun: true.

    pattern ^plan_[0-9a-f]{48}$
  • modestring

    auto (default) runs inline when the operation is sync, one target would run and the class is not send; sync forces inline (422 ACTION_NOT_SYNC when it cannot); async forces a run.

    autosyncasync
  • Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

    0

Responses

200
The finished action and its result, or the dry-run plan.
Show schema

ActionRunResponse

  • dataone ofrequired
    0
    + Show child fields

    One of

    with action

    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
    • resultanyrequired

      The target's result, or null when it was skipped or failed.

      0

    with plan

    • planPlanrequired

      What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0
202
An async run was created (queued); poll it or read the event feed.
Show schema

ActionResponse

  • dataobjectrequired
    0
    + Show child fields
    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0

Errors

400 The request is invalid (VALIDATION_ERROR, CURSOR_MISMATCH, UNSUPPORTED_FILTER) · 401 Missing, invalid, expired or revoked key · 402 Not enough credits (INSUFFICIENT_CREDITS). With an Idempotency-Key this result is stored and replayed: after adding credits, retry with a new Idempotency-Key. · 403 Missing scope, suspended workspace or unavailable identity · 404 Unknown resource or route. A resource in another workspace is also 404 · 409 IDEMPOTENCY_IN_PROGRESS (the first request with this key is still running; `Retry-After` is the lease left, at most 60 s) or IDEMPOTENCY_RESULT_UNAVAILABLE (the original result was too large to store; `details.originalRequestId`). · 422 IDEMPOTENCY_KEY_REUSED (the key was used with another body or operation), or an action that cannot run · 429 Rate limit reached · 500 Unexpected error · 503 The backend is unreachable; retry after `Retry-After`. Every error is {error: {type, code, message, requestId, docUrl}}; see error codes.

curl -X POST "https://app.owlbound.ai/api/v1/actions/score/contact" \
  -H "Authorization: Bearer $OWLBOUND_API_KEY" \
  -H "Owlbound-Version: 2026-10-06" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "kind": "contact",
    "contactId": "<contactId>"
  },
  "dryRun": true
}'

The example is a dry run: it returns a plan and runs, writes and charges nothing. See dry runs and plans.

Enrich

actions.enrich.work_email

Find a person's work email.

post/api/v1/actions/enrich/work_email
Scope
enrich
Credits
32 credits per target
Idempotency-Key
required
Class
spend
Approval floor
none
Runs
Inline for one target, else async
Targets
contact, contacts, records
Max targets
1,000
Dry run
Supported
Writes back
contact

Spend class. Finds a person's work email with the waterfall blitzapi (Owlbound's platform provider), then fullenrich, apollo and zoominfo with the workspace's own connected keys (BYOK, free); the first hit wins. Override the order with input.providers. 32 credits (enrichment.email_found) only for an email the platform provider found that the target did not have; BYOK hits, misses and errors are free. The platform provider needs the person's LinkedIn URL: a target without one (or a request without blitzapi) holds nothing and never calls it. Targets: a contact, contacts, or up to 100 inline records with linkedinUrl or firstName and lastName (and company, domain). A contact that already has an email is skipped ALREADY_HAS_EMAIL (free). A found email is written onto a contact target per output.contact (default fillEmpty). One target runs inline (200, held then settled at what it was charged); more (or mode: "async") create an async run (202), billed per batch of 25. dryRun: true returns the plan with the credit maximum and calls nothing.

Parameters

  • Idempotency-Keyheaderstring

    1 to 255 printable ASCII characters, scoped to the API key (a rotated key shares its predecessor's keys) and kept 24 h. Accepted on every POST, PATCH and DELETE (ignored on GET); required from v1 keys where the operation says x-owlbound-idempotent: required (missing: 400 VALIDATION_ERROR, param: Idempotency-Key). Same key and body after completion: the stored response is replayed with Idempotent-Replayed: true. Results over 64 KB are not stored; their replay is 409 IDEMPOTENCY_RESULT_UNAVAILABLE with details.originalRequestId (check state with a GET). Same key while the first request runs: 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Same key, other body or operation: 422 IDEMPOTENCY_KEY_REUSED. A request that ended 5xx may be retried with the same key. 4xx results are stored and replayed too: a 402 INSUFFICIENT_CREDITS replays even after a top-up, so use a new Idempotency-Key after adding credits.

    min length 1max length 255
  • Owlbound-Dry-Runheaderboolean

    true: same as body field dryRun: true (action operations).

  • Owlbound-Planheaderstring

    A planId from a dry run: same as the body field planId (action operations). A different body planId is 400.

    pattern ^plan_[0-9a-f]{48}$

Request body (required) · application/json

EnrichWorkEmailRequest

  • targetone ofrequired
    0
    + Show child fields
  • 0
  • 0
  • dryRunboolean

    Same as the Owlbound-Dry-Run header.

    0
  • planIdstring

    Apply this dry run's plan (same as Owlbound-Plan). Not with dryRun: true.

    pattern ^plan_[0-9a-f]{48}$
  • modestring

    auto (default) runs inline when the operation is sync, one target would run and the class is not send; sync forces inline (422 ACTION_NOT_SYNC when it cannot); async forces a run.

    autosyncasync
  • Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

    0

Responses

200
The finished action and its result, or the dry-run plan.
Show schema

ActionRunResponse

  • dataone ofrequired
    0
    + Show child fields

    One of

    with action

    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
    • resultanyrequired

      The target's result, or null when it was skipped or failed.

      0

    with plan

    • planPlanrequired

      What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0
202
An async run was created (queued); poll it or read the event feed.
Show schema

ActionResponse

  • dataobjectrequired
    0
    + Show child fields
    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0

Errors

400 The request is invalid (VALIDATION_ERROR, CURSOR_MISMATCH, UNSUPPORTED_FILTER) · 401 Missing, invalid, expired or revoked key · 402 Not enough credits (INSUFFICIENT_CREDITS). With an Idempotency-Key this result is stored and replayed: after adding credits, retry with a new Idempotency-Key. · 403 Missing scope, suspended workspace or unavailable identity · 404 Unknown resource or route. A resource in another workspace is also 404 · 409 IDEMPOTENCY_IN_PROGRESS (the first request with this key is still running; `Retry-After` is the lease left, at most 60 s) or IDEMPOTENCY_RESULT_UNAVAILABLE (the original result was too large to store; `details.originalRequestId`). · 422 IDEMPOTENCY_KEY_REUSED (the key was used with another body or operation), or an action that cannot run · 429 Rate limit reached · 500 Unexpected error · 503 The backend is unreachable; retry after `Retry-After`. Every error is {error: {type, code, message, requestId, docUrl}}; see error codes.

curl -X POST "https://app.owlbound.ai/api/v1/actions/enrich/work_email" \
  -H "Authorization: Bearer $OWLBOUND_API_KEY" \
  -H "Owlbound-Version: 2026-10-06" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "kind": "contact",
    "contactId": "<contactId>"
  },
  "dryRun": true
}'

The example is a dry run: it returns a plan and runs, writes and charges nothing. See dry runs and plans.

actions.enrich.mobile_phone

Find a person's mobile phone.

post/api/v1/actions/enrich/mobile_phone
Scope
enrich
Credits
145 credits per target
Idempotency-Key
required
Class
spend
Approval floor
none
Runs
Inline for one target, else async
Targets
contact, contacts, records
Max targets
1,000
Dry run
Supported
Writes back
contact

Spend class. Finds a person's mobile phone with Owlbound's platform provider (blitzapi) from their LinkedIn URL. 145 credits (enrichment.phone_found) only for a phone that was found and that the target did not have; misses and errors are free. Targets: a contact (needs a LinkedIn URL, else skipped NO_LINKEDIN_URL), contacts, or up to 100 inline records with linkedinUrl. A contact that already has a phone is skipped ALREADY_HAS_PHONE (free). A found phone is written onto a contact target per output.contact (default fillEmpty). One target runs inline (200); more (or mode: "async") create an async run (202), billed per batch of 25. dryRun: true returns the plan and calls nothing.

Parameters

  • Idempotency-Keyheaderstring

    1 to 255 printable ASCII characters, scoped to the API key (a rotated key shares its predecessor's keys) and kept 24 h. Accepted on every POST, PATCH and DELETE (ignored on GET); required from v1 keys where the operation says x-owlbound-idempotent: required (missing: 400 VALIDATION_ERROR, param: Idempotency-Key). Same key and body after completion: the stored response is replayed with Idempotent-Replayed: true. Results over 64 KB are not stored; their replay is 409 IDEMPOTENCY_RESULT_UNAVAILABLE with details.originalRequestId (check state with a GET). Same key while the first request runs: 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Same key, other body or operation: 422 IDEMPOTENCY_KEY_REUSED. A request that ended 5xx may be retried with the same key. 4xx results are stored and replayed too: a 402 INSUFFICIENT_CREDITS replays even after a top-up, so use a new Idempotency-Key after adding credits.

    min length 1max length 255
  • Owlbound-Dry-Runheaderboolean

    true: same as body field dryRun: true (action operations).

  • Owlbound-Planheaderstring

    A planId from a dry run: same as the body field planId (action operations). A different body planId is 400.

    pattern ^plan_[0-9a-f]{48}$

Request body (required) · application/json

EnrichMobilePhoneRequest

  • targetone ofrequired
    0
    + Show child fields
  • 0
  • 0
  • dryRunboolean

    Same as the Owlbound-Dry-Run header.

    0
  • planIdstring

    Apply this dry run's plan (same as Owlbound-Plan). Not with dryRun: true.

    pattern ^plan_[0-9a-f]{48}$
  • modestring

    auto (default) runs inline when the operation is sync, one target would run and the class is not send; sync forces inline (422 ACTION_NOT_SYNC when it cannot); async forces a run.

    autosyncasync
  • Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

    0

Responses

200
The finished action and its result, or the dry-run plan.
Show schema

ActionRunResponse

  • dataone ofrequired
    0
    + Show child fields

    One of

    with action

    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
    • resultanyrequired

      The target's result, or null when it was skipped or failed.

      0

    with plan

    • planPlanrequired

      What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0
202
An async run was created (queued); poll it or read the event feed.
Show schema

ActionResponse

  • dataobjectrequired
    0
    + Show child fields
    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0

Errors

400 The request is invalid (VALIDATION_ERROR, CURSOR_MISMATCH, UNSUPPORTED_FILTER) · 401 Missing, invalid, expired or revoked key · 402 Not enough credits (INSUFFICIENT_CREDITS). With an Idempotency-Key this result is stored and replayed: after adding credits, retry with a new Idempotency-Key. · 403 Missing scope, suspended workspace or unavailable identity · 404 Unknown resource or route. A resource in another workspace is also 404 · 409 IDEMPOTENCY_IN_PROGRESS (the first request with this key is still running; `Retry-After` is the lease left, at most 60 s) or IDEMPOTENCY_RESULT_UNAVAILABLE (the original result was too large to store; `details.originalRequestId`). · 422 IDEMPOTENCY_KEY_REUSED (the key was used with another body or operation), or an action that cannot run · 429 Rate limit reached · 500 Unexpected error · 503 The backend is unreachable; retry after `Retry-After`. Every error is {error: {type, code, message, requestId, docUrl}}; see error codes.

curl -X POST "https://app.owlbound.ai/api/v1/actions/enrich/mobile_phone" \
  -H "Authorization: Bearer $OWLBOUND_API_KEY" \
  -H "Owlbound-Version: 2026-10-06" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "kind": "contact",
    "contactId": "<contactId>"
  },
  "dryRun": true
}'

The example is a dry run: it returns a plan and runs, writes and charges nothing. See dry runs and plans.

Ai

actions.ai.generate_message

Write a personalized message for a contact with AI.

post/api/v1/actions/ai/generate_message
Scope
enrich
Credits
18 credits per target
Idempotency-Key
required
Class
spend
Approval floor
none
Runs
Inline for one target, else async
Targets
contact, contacts
Max targets
1,000
Dry run
Supported

Spend class. Writes one message per contact with the message engine (the workspace's voice, ICP psychology, offers and the contact's data, as the app's playground does) and stores it in the generated message history. input.channel and input.messageType are required; customPrompt, style and sequenceId (this workspace's) are optional. 18 credits (sequence.message.generate) per generated message, charged once by the action (the generator's own debit is skipped); a failed generation is free. A contact without a first name is skipped MISSING_NAME. Nothing is sent. One target runs inline (200 {data: {action, result}}, its price held then settled); more (or mode: "async") create an async run (202), billed per batch of 25. dryRun: true returns the plan and calls nothing.

Parameters

  • Idempotency-Keyheaderstring

    1 to 255 printable ASCII characters, scoped to the API key (a rotated key shares its predecessor's keys) and kept 24 h. Accepted on every POST, PATCH and DELETE (ignored on GET); required from v1 keys where the operation says x-owlbound-idempotent: required (missing: 400 VALIDATION_ERROR, param: Idempotency-Key). Same key and body after completion: the stored response is replayed with Idempotent-Replayed: true. Results over 64 KB are not stored; their replay is 409 IDEMPOTENCY_RESULT_UNAVAILABLE with details.originalRequestId (check state with a GET). Same key while the first request runs: 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Same key, other body or operation: 422 IDEMPOTENCY_KEY_REUSED. A request that ended 5xx may be retried with the same key. 4xx results are stored and replayed too: a 402 INSUFFICIENT_CREDITS replays even after a top-up, so use a new Idempotency-Key after adding credits.

    min length 1max length 255
  • Owlbound-Dry-Runheaderboolean

    true: same as body field dryRun: true (action operations).

  • Owlbound-Planheaderstring

    A planId from a dry run: same as the body field planId (action operations). A different body planId is 400.

    pattern ^plan_[0-9a-f]{48}$

Request body (required) · application/json

AiGenerateMessageRequest

  • targetone ofrequired
    0
    + Show child fields
  • 0
  • dryRunboolean

    Same as the Owlbound-Dry-Run header.

    0
  • planIdstring

    Apply this dry run's plan (same as Owlbound-Plan). Not with dryRun: true.

    pattern ^plan_[0-9a-f]{48}$
  • modestring

    auto (default) runs inline when the operation is sync, one target would run and the class is not send; sync forces inline (422 ACTION_NOT_SYNC when it cannot); async forces a run.

    autosyncasync
  • Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

    0

Responses

200
The finished action and its result, or the dry-run plan.
Show schema

ActionRunResponse

  • dataone ofrequired
    0
    + Show child fields

    One of

    with action

    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
    • resultanyrequired

      The target's result, or null when it was skipped or failed.

      0

    with plan

    • planPlanrequired

      What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0
202
An async run was created (queued); poll it or read the event feed.
Show schema

ActionResponse

  • dataobjectrequired
    0
    + Show child fields
    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0

Errors

400 The request is invalid (VALIDATION_ERROR, CURSOR_MISMATCH, UNSUPPORTED_FILTER) · 401 Missing, invalid, expired or revoked key · 402 Not enough credits (INSUFFICIENT_CREDITS). With an Idempotency-Key this result is stored and replayed: after adding credits, retry with a new Idempotency-Key. · 403 Missing scope, suspended workspace or unavailable identity · 404 Unknown resource or route. A resource in another workspace is also 404 · 409 IDEMPOTENCY_IN_PROGRESS (the first request with this key is still running; `Retry-After` is the lease left, at most 60 s) or IDEMPOTENCY_RESULT_UNAVAILABLE (the original result was too large to store; `details.originalRequestId`). · 422 IDEMPOTENCY_KEY_REUSED (the key was used with another body or operation), or an action that cannot run · 429 Rate limit reached · 500 Unexpected error · 503 The backend is unreachable; retry after `Retry-After`. Every error is {error: {type, code, message, requestId, docUrl}}; see error codes.

curl -X POST "https://app.owlbound.ai/api/v1/actions/ai/generate_message" \
  -H "Authorization: Bearer $OWLBOUND_API_KEY" \
  -H "Owlbound-Version: 2026-10-06" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "kind": "contact",
    "contactId": "<contactId>"
  },
  "input": {
    "channel": "linkedin",
    "messageType": "connection_request"
  },
  "dryRun": true
}'

The example is a dry run: it returns a plan and runs, writes and charges nothing. See dry runs and plans.

actions.ai.icebreaker

Write an icebreaker for a contact with AI.

post/api/v1/actions/ai/icebreaker
Scope
enrich
Credits
18 credits per target
Idempotency-Key
required
Class
spend
Approval floor
none
Runs
Inline for one target, else async
Targets
contact, contacts
Max targets
1,000
Dry run
Supported

Spend class. Writes one icebreaker per contact (type from the relationship when input.type is auto or absent) and saves it on the contact's icebreakers, as the app's icebreaker button does. 18 credits (sequence.message.generate) per icebreaker, charged once by the action (the generator's own debit is skipped); a failed generation is free. A contact without a first name is skipped MISSING_NAME. Nothing is sent. One target runs inline (200 {data: {action, result}}, its price held then settled); more (or mode: "async") create an async run (202), billed per batch of 25. dryRun: true returns the plan and calls nothing.

Parameters

  • Idempotency-Keyheaderstring

    1 to 255 printable ASCII characters, scoped to the API key (a rotated key shares its predecessor's keys) and kept 24 h. Accepted on every POST, PATCH and DELETE (ignored on GET); required from v1 keys where the operation says x-owlbound-idempotent: required (missing: 400 VALIDATION_ERROR, param: Idempotency-Key). Same key and body after completion: the stored response is replayed with Idempotent-Replayed: true. Results over 64 KB are not stored; their replay is 409 IDEMPOTENCY_RESULT_UNAVAILABLE with details.originalRequestId (check state with a GET). Same key while the first request runs: 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Same key, other body or operation: 422 IDEMPOTENCY_KEY_REUSED. A request that ended 5xx may be retried with the same key. 4xx results are stored and replayed too: a 402 INSUFFICIENT_CREDITS replays even after a top-up, so use a new Idempotency-Key after adding credits.

    min length 1max length 255
  • Owlbound-Dry-Runheaderboolean

    true: same as body field dryRun: true (action operations).

  • Owlbound-Planheaderstring

    A planId from a dry run: same as the body field planId (action operations). A different body planId is 400.

    pattern ^plan_[0-9a-f]{48}$

Request body (required) · application/json

AiIcebreakerRequest

  • targetone ofrequired
    0
    + Show child fields
  • 0
  • dryRunboolean

    Same as the Owlbound-Dry-Run header.

    0
  • planIdstring

    Apply this dry run's plan (same as Owlbound-Plan). Not with dryRun: true.

    pattern ^plan_[0-9a-f]{48}$
  • modestring

    auto (default) runs inline when the operation is sync, one target would run and the class is not send; sync forces inline (422 ACTION_NOT_SYNC when it cannot); async forces a run.

    autosyncasync
  • Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

    0

Responses

200
The finished action and its result, or the dry-run plan.
Show schema

ActionRunResponse

  • dataone ofrequired
    0
    + Show child fields

    One of

    with action

    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
    • resultanyrequired

      The target's result, or null when it was skipped or failed.

      0

    with plan

    • planPlanrequired

      What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0
202
An async run was created (queued); poll it or read the event feed.
Show schema

ActionResponse

  • dataobjectrequired
    0
    + Show child fields
    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0

Errors

400 The request is invalid (VALIDATION_ERROR, CURSOR_MISMATCH, UNSUPPORTED_FILTER) · 401 Missing, invalid, expired or revoked key · 402 Not enough credits (INSUFFICIENT_CREDITS). With an Idempotency-Key this result is stored and replayed: after adding credits, retry with a new Idempotency-Key. · 403 Missing scope, suspended workspace or unavailable identity · 404 Unknown resource or route. A resource in another workspace is also 404 · 409 IDEMPOTENCY_IN_PROGRESS (the first request with this key is still running; `Retry-After` is the lease left, at most 60 s) or IDEMPOTENCY_RESULT_UNAVAILABLE (the original result was too large to store; `details.originalRequestId`). · 422 IDEMPOTENCY_KEY_REUSED (the key was used with another body or operation), or an action that cannot run · 429 Rate limit reached · 500 Unexpected error · 503 The backend is unreachable; retry after `Retry-After`. Every error is {error: {type, code, message, requestId, docUrl}}; see error codes.

curl -X POST "https://app.owlbound.ai/api/v1/actions/ai/icebreaker" \
  -H "Authorization: Bearer $OWLBOUND_API_KEY" \
  -H "Owlbound-Version: 2026-10-06" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "kind": "contact",
    "contactId": "<contactId>"
  },
  "dryRun": true
}'

The example is a dry run: it returns a plan and runs, writes and charges nothing. See dry runs and plans.

actions.ai.subject

Write an email subject line for a contact with AI.

post/api/v1/actions/ai/subject
Scope
enrich
Credits
18 credits per target
Idempotency-Key
required
Class
spend
Approval floor
none
Runs
Inline for one target, else async
Targets
contact, contacts
Max targets
1,000
Dry run
Supported

Spend class. Writes one subject line (at most 200 characters) per contact from input.prompt and the contact's name, title, company and industry, optionally with the email input.body. 18 credits (sequence.message.generate) per subject; a failed generation is free. Nothing is stored or sent. One target runs inline (200 {data: {action, result}}, its price held then settled); more (or mode: "async") create an async run (202), billed per batch of 25. dryRun: true returns the plan and calls nothing.

Parameters

  • Idempotency-Keyheaderstring

    1 to 255 printable ASCII characters, scoped to the API key (a rotated key shares its predecessor's keys) and kept 24 h. Accepted on every POST, PATCH and DELETE (ignored on GET); required from v1 keys where the operation says x-owlbound-idempotent: required (missing: 400 VALIDATION_ERROR, param: Idempotency-Key). Same key and body after completion: the stored response is replayed with Idempotent-Replayed: true. Results over 64 KB are not stored; their replay is 409 IDEMPOTENCY_RESULT_UNAVAILABLE with details.originalRequestId (check state with a GET). Same key while the first request runs: 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Same key, other body or operation: 422 IDEMPOTENCY_KEY_REUSED. A request that ended 5xx may be retried with the same key. 4xx results are stored and replayed too: a 402 INSUFFICIENT_CREDITS replays even after a top-up, so use a new Idempotency-Key after adding credits.

    min length 1max length 255
  • Owlbound-Dry-Runheaderboolean

    true: same as body field dryRun: true (action operations).

  • Owlbound-Planheaderstring

    A planId from a dry run: same as the body field planId (action operations). A different body planId is 400.

    pattern ^plan_[0-9a-f]{48}$

Request body (required) · application/json

AiSubjectRequest

  • targetone ofrequired
    0
    + Show child fields
  • inputAiSubjectInputrequired
    0
  • dryRunboolean

    Same as the Owlbound-Dry-Run header.

    0
  • planIdstring

    Apply this dry run's plan (same as Owlbound-Plan). Not with dryRun: true.

    pattern ^plan_[0-9a-f]{48}$
  • modestring

    auto (default) runs inline when the operation is sync, one target would run and the class is not send; sync forces inline (422 ACTION_NOT_SYNC when it cannot); async forces a run.

    autosyncasync
  • Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

    0

Responses

200
The finished action and its result, or the dry-run plan.
Show schema

ActionRunResponse

  • dataone ofrequired
    0
    + Show child fields

    One of

    with action

    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
    • resultanyrequired

      The target's result, or null when it was skipped or failed.

      0

    with plan

    • planPlanrequired

      What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0
202
An async run was created (queued); poll it or read the event feed.
Show schema

ActionResponse

  • dataobjectrequired
    0
    + Show child fields
    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0

Errors

400 The request is invalid (VALIDATION_ERROR, CURSOR_MISMATCH, UNSUPPORTED_FILTER) · 401 Missing, invalid, expired or revoked key · 402 Not enough credits (INSUFFICIENT_CREDITS). With an Idempotency-Key this result is stored and replayed: after adding credits, retry with a new Idempotency-Key. · 403 Missing scope, suspended workspace or unavailable identity · 404 Unknown resource or route. A resource in another workspace is also 404 · 409 IDEMPOTENCY_IN_PROGRESS (the first request with this key is still running; `Retry-After` is the lease left, at most 60 s) or IDEMPOTENCY_RESULT_UNAVAILABLE (the original result was too large to store; `details.originalRequestId`). · 422 IDEMPOTENCY_KEY_REUSED (the key was used with another body or operation), or an action that cannot run · 429 Rate limit reached · 500 Unexpected error · 503 The backend is unreachable; retry after `Retry-After`. Every error is {error: {type, code, message, requestId, docUrl}}; see error codes.

curl -X POST "https://app.owlbound.ai/api/v1/actions/ai/subject" \
  -H "Authorization: Bearer $OWLBOUND_API_KEY" \
  -H "Owlbound-Version: 2026-10-06" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "kind": "contact",
    "contactId": "<contactId>"
  },
  "input": {
    "prompt": "<prompt>"
  },
  "dryRun": true
}'

The example is a dry run: it returns a plan and runs, writes and charges nothing. See dry runs and plans.

Research

actions.research.web

Search the web.

post/api/v1/actions/research/web
Scope
enrich
Credits
68 credits per target
Idempotency-Key
required
Class
spend
Approval floor
none
Runs
Inline for one target, else async
Targets
records
Max targets
1,000
Dry run
Supported

Spend class. One web search per inline record {query} (1 to 300 characters) through our web search provider, with input.limit (1 to 10, default 5), includeDomains and timeRange. Returns the hits (title, URL, domain, description; no page bodies: read one with actions.research.read_page). 68 credits (web.research) per search that returns at least one hit; no hit or an error is free. One target runs inline (200 {data: {action, result}}, its price held then settled); more (or mode: "async") create an async run (202), billed per batch of 25. dryRun: true returns the plan and calls nothing.

Parameters

  • Idempotency-Keyheaderstring

    1 to 255 printable ASCII characters, scoped to the API key (a rotated key shares its predecessor's keys) and kept 24 h. Accepted on every POST, PATCH and DELETE (ignored on GET); required from v1 keys where the operation says x-owlbound-idempotent: required (missing: 400 VALIDATION_ERROR, param: Idempotency-Key). Same key and body after completion: the stored response is replayed with Idempotent-Replayed: true. Results over 64 KB are not stored; their replay is 409 IDEMPOTENCY_RESULT_UNAVAILABLE with details.originalRequestId (check state with a GET). Same key while the first request runs: 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Same key, other body or operation: 422 IDEMPOTENCY_KEY_REUSED. A request that ended 5xx may be retried with the same key. 4xx results are stored and replayed too: a 402 INSUFFICIENT_CREDITS replays even after a top-up, so use a new Idempotency-Key after adding credits.

    min length 1max length 255
  • Owlbound-Dry-Runheaderboolean

    true: same as body field dryRun: true (action operations).

  • Owlbound-Planheaderstring

    A planId from a dry run: same as the body field planId (action operations). A different body planId is 400.

    pattern ^plan_[0-9a-f]{48}$

Request body (required) · application/json

ResearchWebRequest

  • 0
  • 0
  • dryRunboolean

    Same as the Owlbound-Dry-Run header.

    0
  • planIdstring

    Apply this dry run's plan (same as Owlbound-Plan). Not with dryRun: true.

    pattern ^plan_[0-9a-f]{48}$
  • modestring

    auto (default) runs inline when the operation is sync, one target would run and the class is not send; sync forces inline (422 ACTION_NOT_SYNC when it cannot); async forces a run.

    autosyncasync
  • Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

    0

Responses

200
The finished action and its result, or the dry-run plan.
Show schema

ActionRunResponse

  • dataone ofrequired
    0
    + Show child fields

    One of

    with action

    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
    • resultanyrequired

      The target's result, or null when it was skipped or failed.

      0

    with plan

    • planPlanrequired

      What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0
202
An async run was created (queued); poll it or read the event feed.
Show schema

ActionResponse

  • dataobjectrequired
    0
    + Show child fields
    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0

Errors

400 The request is invalid (VALIDATION_ERROR, CURSOR_MISMATCH, UNSUPPORTED_FILTER) · 401 Missing, invalid, expired or revoked key · 402 Not enough credits (INSUFFICIENT_CREDITS). With an Idempotency-Key this result is stored and replayed: after adding credits, retry with a new Idempotency-Key. · 403 Missing scope, suspended workspace or unavailable identity · 404 Unknown resource or route. A resource in another workspace is also 404 · 409 IDEMPOTENCY_IN_PROGRESS (the first request with this key is still running; `Retry-After` is the lease left, at most 60 s) or IDEMPOTENCY_RESULT_UNAVAILABLE (the original result was too large to store; `details.originalRequestId`). · 422 IDEMPOTENCY_KEY_REUSED (the key was used with another body or operation), or an action that cannot run · 429 Rate limit reached · 500 Unexpected error · 503 The backend is unreachable; retry after `Retry-After`. Every error is {error: {type, code, message, requestId, docUrl}}; see error codes.

curl -X POST "https://app.owlbound.ai/api/v1/actions/research/web" \
  -H "Authorization: Bearer $OWLBOUND_API_KEY" \
  -H "Owlbound-Version: 2026-10-06" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "kind": "records",
    "records": [
      {
        "query": "<query>"
      }
    ]
  },
  "dryRun": true
}'

The example is a dry run: it returns a plan and runs, writes and charges nothing. See dry runs and plans.

actions.research.read_page

Read a public web page.

post/api/v1/actions/research/read_page
Scope
enrich
Credits
68 credits per target
Idempotency-Key
required
Class
spend
Approval floor
none
Runs
Inline for one target, else async
Targets
records
Max targets
1,000
Dry run
Supported

Spend class. Reads each inline record {url} (a public http(s) page; private and local hosts are refused INVALID_URL) and returns it as markdown, cut to 5,000 characters. 68 credits (web.research) per page read; an empty page or an error is free. One target runs inline (200 {data: {action, result}}, its price held then settled); more (or mode: "async") create an async run (202), billed per batch of 25. dryRun: true returns the plan and calls nothing.

Parameters

  • Idempotency-Keyheaderstring

    1 to 255 printable ASCII characters, scoped to the API key (a rotated key shares its predecessor's keys) and kept 24 h. Accepted on every POST, PATCH and DELETE (ignored on GET); required from v1 keys where the operation says x-owlbound-idempotent: required (missing: 400 VALIDATION_ERROR, param: Idempotency-Key). Same key and body after completion: the stored response is replayed with Idempotent-Replayed: true. Results over 64 KB are not stored; their replay is 409 IDEMPOTENCY_RESULT_UNAVAILABLE with details.originalRequestId (check state with a GET). Same key while the first request runs: 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Same key, other body or operation: 422 IDEMPOTENCY_KEY_REUSED. A request that ended 5xx may be retried with the same key. 4xx results are stored and replayed too: a 402 INSUFFICIENT_CREDITS replays even after a top-up, so use a new Idempotency-Key after adding credits.

    min length 1max length 255
  • Owlbound-Dry-Runheaderboolean

    true: same as body field dryRun: true (action operations).

  • Owlbound-Planheaderstring

    A planId from a dry run: same as the body field planId (action operations). A different body planId is 400.

    pattern ^plan_[0-9a-f]{48}$

Request body (required) · application/json

ResearchReadPageRequest

  • 0
  • inputobject
    0
  • dryRunboolean

    Same as the Owlbound-Dry-Run header.

    0
  • planIdstring

    Apply this dry run's plan (same as Owlbound-Plan). Not with dryRun: true.

    pattern ^plan_[0-9a-f]{48}$
  • modestring

    auto (default) runs inline when the operation is sync, one target would run and the class is not send; sync forces inline (422 ACTION_NOT_SYNC when it cannot); async forces a run.

    autosyncasync
  • Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

    0

Responses

200
The finished action and its result, or the dry-run plan.
Show schema

ActionRunResponse

  • dataone ofrequired
    0
    + Show child fields

    One of

    with action

    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
    • resultanyrequired

      The target's result, or null when it was skipped or failed.

      0

    with plan

    • planPlanrequired

      What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0
202
An async run was created (queued); poll it or read the event feed.
Show schema

ActionResponse

  • dataobjectrequired
    0
    + Show child fields
    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0

Errors

400 The request is invalid (VALIDATION_ERROR, CURSOR_MISMATCH, UNSUPPORTED_FILTER) · 401 Missing, invalid, expired or revoked key · 402 Not enough credits (INSUFFICIENT_CREDITS). With an Idempotency-Key this result is stored and replayed: after adding credits, retry with a new Idempotency-Key. · 403 Missing scope, suspended workspace or unavailable identity · 404 Unknown resource or route. A resource in another workspace is also 404 · 409 IDEMPOTENCY_IN_PROGRESS (the first request with this key is still running; `Retry-After` is the lease left, at most 60 s) or IDEMPOTENCY_RESULT_UNAVAILABLE (the original result was too large to store; `details.originalRequestId`). · 422 IDEMPOTENCY_KEY_REUSED (the key was used with another body or operation), or an action that cannot run · 429 Rate limit reached · 500 Unexpected error · 503 The backend is unreachable; retry after `Retry-After`. Every error is {error: {type, code, message, requestId, docUrl}}; see error codes.

curl -X POST "https://app.owlbound.ai/api/v1/actions/research/read_page" \
  -H "Authorization: Bearer $OWLBOUND_API_KEY" \
  -H "Owlbound-Version: 2026-10-06" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "kind": "records",
    "records": [
      {
        "url": "https://example.com"
      }
    ]
  },
  "dryRun": true
}'

The example is a dry run: it returns a plan and runs, writes and charges nothing. See dry runs and plans.

actions.research.company_website

Research a company from its website.

post/api/v1/actions/research/company_website
Scope
enrich
Credits
65 credits per target
Idempotency-Key
required
Class
spend
Approval floor
none
Runs
Inline for one target, else async
Targets
contact, contacts, records
Max targets
1,000
Dry run
Supported

Spend class. Crawls the company's homepage and reads it with AI: name, description, value proposition, industry, markets, size, headquarters, founding year, differentiators, notable clients and logo. Targets: a contact (its company domain, else skipped NO_DOMAIN), contacts, or up to 100 inline records with domain. input.depth is quick (the only depth today). 65 credits (company.research.quick) per company researched, charged once by the action (the crawler's own debit is skipped); a failed crawl is free. One target runs inline (200 {data: {action, result}}, its price held then settled); more (or mode: "async") create an async run (202), billed per batch of 25. dryRun: true returns the plan and calls nothing.

Parameters

  • Idempotency-Keyheaderstring

    1 to 255 printable ASCII characters, scoped to the API key (a rotated key shares its predecessor's keys) and kept 24 h. Accepted on every POST, PATCH and DELETE (ignored on GET); required from v1 keys where the operation says x-owlbound-idempotent: required (missing: 400 VALIDATION_ERROR, param: Idempotency-Key). Same key and body after completion: the stored response is replayed with Idempotent-Replayed: true. Results over 64 KB are not stored; their replay is 409 IDEMPOTENCY_RESULT_UNAVAILABLE with details.originalRequestId (check state with a GET). Same key while the first request runs: 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Same key, other body or operation: 422 IDEMPOTENCY_KEY_REUSED. A request that ended 5xx may be retried with the same key. 4xx results are stored and replayed too: a 402 INSUFFICIENT_CREDITS replays even after a top-up, so use a new Idempotency-Key after adding credits.

    min length 1max length 255
  • Owlbound-Dry-Runheaderboolean

    true: same as body field dryRun: true (action operations).

  • Owlbound-Planheaderstring

    A planId from a dry run: same as the body field planId (action operations). A different body planId is 400.

    pattern ^plan_[0-9a-f]{48}$

Request body (required) · application/json

ResearchCompanyWebsiteRequest

  • targetone ofrequired
    0
    + Show child fields
  • inputobject
    0
    + Show child fields
    • depthstring

      The homepage only (the multi-page crawl is a later slice).

      quick
  • dryRunboolean

    Same as the Owlbound-Dry-Run header.

    0
  • planIdstring

    Apply this dry run's plan (same as Owlbound-Plan). Not with dryRun: true.

    pattern ^plan_[0-9a-f]{48}$
  • modestring

    auto (default) runs inline when the operation is sync, one target would run and the class is not send; sync forces inline (422 ACTION_NOT_SYNC when it cannot); async forces a run.

    autosyncasync
  • Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

    0

Responses

200
The finished action and its result, or the dry-run plan.
Show schema

ActionRunResponse

  • dataone ofrequired
    0
    + Show child fields

    One of

    with action

    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
    • resultanyrequired

      The target's result, or null when it was skipped or failed.

      0

    with plan

    • planPlanrequired

      What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0
202
An async run was created (queued); poll it or read the event feed.
Show schema

ActionResponse

  • dataobjectrequired
    0
    + Show child fields
    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0

Errors

400 The request is invalid (VALIDATION_ERROR, CURSOR_MISMATCH, UNSUPPORTED_FILTER) · 401 Missing, invalid, expired or revoked key · 402 Not enough credits (INSUFFICIENT_CREDITS). With an Idempotency-Key this result is stored and replayed: after adding credits, retry with a new Idempotency-Key. · 403 Missing scope, suspended workspace or unavailable identity · 404 Unknown resource or route. A resource in another workspace is also 404 · 409 IDEMPOTENCY_IN_PROGRESS (the first request with this key is still running; `Retry-After` is the lease left, at most 60 s) or IDEMPOTENCY_RESULT_UNAVAILABLE (the original result was too large to store; `details.originalRequestId`). · 422 IDEMPOTENCY_KEY_REUSED (the key was used with another body or operation), or an action that cannot run · 429 Rate limit reached · 500 Unexpected error · 503 The backend is unreachable; retry after `Retry-After`. Every error is {error: {type, code, message, requestId, docUrl}}; see error codes.

curl -X POST "https://app.owlbound.ai/api/v1/actions/research/company_website" \
  -H "Authorization: Bearer $OWLBOUND_API_KEY" \
  -H "Owlbound-Version: 2026-10-06" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "kind": "contact",
    "contactId": "<contactId>"
  },
  "dryRun": true
}'

The example is a dry run: it returns a plan and runs, writes and charges nothing. See dry runs and plans.

actions.research.company_news

Find recent news about a company.

post/api/v1/actions/research/company_news
Scope
enrich
Credits
32 credits per target
Idempotency-Key
required
Class
spend
Approval floor
none
Runs
Inline for one target, else async
Targets
contact, contacts, records
Max targets
1,000
Dry run
Supported

Spend class. Searches recent news about each company (funding, hiring, launches, leadership changes) in business news, careers, tech and social sources. Targets: a contact (its company, else skipped NO_COMPANY), contacts, or up to 100 inline records with companyName (and companyDomain). 32 credits (company.news_search) per company with at least one news hit, charged once by the action (the search's own debit is skipped); no news or an error is free. One target runs inline (200 {data: {action, result}}, its price held then settled); more (or mode: "async") create an async run (202), billed per batch of 25. dryRun: true returns the plan and calls nothing.

Parameters

  • Idempotency-Keyheaderstring

    1 to 255 printable ASCII characters, scoped to the API key (a rotated key shares its predecessor's keys) and kept 24 h. Accepted on every POST, PATCH and DELETE (ignored on GET); required from v1 keys where the operation says x-owlbound-idempotent: required (missing: 400 VALIDATION_ERROR, param: Idempotency-Key). Same key and body after completion: the stored response is replayed with Idempotent-Replayed: true. Results over 64 KB are not stored; their replay is 409 IDEMPOTENCY_RESULT_UNAVAILABLE with details.originalRequestId (check state with a GET). Same key while the first request runs: 409 IDEMPOTENCY_IN_PROGRESS with Retry-After. Same key, other body or operation: 422 IDEMPOTENCY_KEY_REUSED. A request that ended 5xx may be retried with the same key. 4xx results are stored and replayed too: a 402 INSUFFICIENT_CREDITS replays even after a top-up, so use a new Idempotency-Key after adding credits.

    min length 1max length 255
  • Owlbound-Dry-Runheaderboolean

    true: same as body field dryRun: true (action operations).

  • Owlbound-Planheaderstring

    A planId from a dry run: same as the body field planId (action operations). A different body planId is 400.

    pattern ^plan_[0-9a-f]{48}$

Request body (required) · application/json

ResearchCompanyNewsRequest

  • targetone ofrequired
    0
    + Show child fields
  • inputobject
    0
  • dryRunboolean

    Same as the Owlbound-Dry-Run header.

    0
  • planIdstring

    Apply this dry run's plan (same as Owlbound-Plan). Not with dryRun: true.

    pattern ^plan_[0-9a-f]{48}$
  • modestring

    auto (default) runs inline when the operation is sync, one target would run and the class is not send; sync forces inline (422 ACTION_NOT_SYNC when it cannot); async forces a run.

    autosyncasync
  • Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

    0

Responses

200
The finished action and its result, or the dry-run plan.
Show schema

ActionRunResponse

  • dataone ofrequired
    0
    + Show child fields

    One of

    with action

    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
    • resultanyrequired

      The target's result, or null when it was skipped or failed.

      0

    with plan

    • planPlanrequired

      What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0
202
An async run was created (queued); poll it or read the event feed.
Show schema

ActionResponse

  • dataobjectrequired
    0
    + Show child fields
    • actionActionrequired

      One action run. Read it again with GET /api/v1/actions/{id}.

      0
  • metaResponseMetarequired

    Metadata on every success response.

    0

Errors

400 The request is invalid (VALIDATION_ERROR, CURSOR_MISMATCH, UNSUPPORTED_FILTER) · 401 Missing, invalid, expired or revoked key · 402 Not enough credits (INSUFFICIENT_CREDITS). With an Idempotency-Key this result is stored and replayed: after adding credits, retry with a new Idempotency-Key. · 403 Missing scope, suspended workspace or unavailable identity · 404 Unknown resource or route. A resource in another workspace is also 404 · 409 IDEMPOTENCY_IN_PROGRESS (the first request with this key is still running; `Retry-After` is the lease left, at most 60 s) or IDEMPOTENCY_RESULT_UNAVAILABLE (the original result was too large to store; `details.originalRequestId`). · 422 IDEMPOTENCY_KEY_REUSED (the key was used with another body or operation), or an action that cannot run · 429 Rate limit reached · 500 Unexpected error · 503 The backend is unreachable; retry after `Retry-After`. Every error is {error: {type, code, message, requestId, docUrl}}; see error codes.

curl -X POST "https://app.owlbound.ai/api/v1/actions/research/company_news" \
  -H "Authorization: Bearer $OWLBOUND_API_KEY" \
  -H "Owlbound-Version: 2026-10-06" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "target": {
    "kind": "contact",
    "contactId": "<contactId>"
  },
  "dryRun": true
}'

The example is a dry run: it returns a plan and runs, writes and charges nothing. See dry runs and plans.

Models on this page

Shared objects the operations above link to. Clients must ignore fields they do not know.

ActionTargetContactobject
  • kind"contact"required
    0
  • contactIdstringrequired
    0
ActionTargetContactsobject
  • kind"contacts"required
    0
  • contactIdsarray of stringrequired

    Deduplicated, order kept.

    min items 1max items 1000
ScoreContactInputobject
  • icpProfileIdstring

    The ICP (audience) to score against; default the contact's own.

    0
ActionNotifyobject

Events for this action. targetEvents: true also writes one action.target.completed / action.target.failed event per target (feed and webhooks); without it only action-level events are written, to keep the volume down. webhook is accepted and has no effect (webhook endpoints subscribe by event type).

  • targetEventsboolean
    default false
  • webhookboolean
    0
Actionobject

One action run. Read it again with GET /api/v1/actions/{id}.

  • idstringrequired
    0
  • kindstringrequired

    The operation id.

    0
  • classstringrequired

    Safety class: decides scope, approval, caps and enforcement.

    readwritespendexternal_writesend
  • statusstringrequired
    pending_approvalqueuedrunningsucceededfailedrejectedcanceledexpiredpartial
  • identityIdstring | nullrequired
    0
  • approvalActionApproval | nullrequired
    0
  • costobjectrequired
    0
    + Show child fields
    • estimatednumberrequired
      0
    • chargednumberrequired
      0
    • reservationIdstring | nullrequired
      0
  • countsActionCountsrequired
    0
  • targetobjectrequired
    0
    + Show child fields
    • kindstringrequired
      0
    • tableIdstring
      0
    • viewIdstring
      0
    • columnIdstring

      The send column this action runs (tables.rows.push target column).

      0
  • outputobject | nullrequired
    0
  • resultanyrequired

    The single target's result (sync), or null; bulk results are per target.

    0
  • errorActionErrorrequired
    0
  • actorActionActorrequired

    Who started the action. agent is an LLM-driven caller (the in-app agent, MCP) acting for the key or member in onBehalfOf.

    0
  • createdAtnumberrequired
    0
  • updatedAtnumberrequired
    0
ActionApprovalobject
  • modestringrequired
    nonealwaysover_threshold
  • urlstring | nullrequired
    0
  • decidedBystring | nullrequired
    0
  • decidedAtnumber | nullrequired
    0
  • expiresAtnumber | nullrequired
    0
ActionCountsobject
  • totalintegerrequired
    0
  • queuedintegerrequired
    0
  • scheduledintegerrequired
    0
  • runningintegerrequired
    0
  • succeededintegerrequired
    0
  • skippedintegerrequired
    0
  • failedintegerrequired
    0
  • canceledintegerrequired
    0
ActionErrorobject
  • codestringrequired
    0
  • messagestringrequired
    0
ActionActorobject

Who started the action. agent is an LLM-driven caller (the in-app agent, MCP) acting for the key or member in onBehalfOf.

  • kindstringrequired
    apiKeysessionagentjob
  • idstringrequired

    API key id, user id, agent run id or job id.

    0
  • onBehalfOfobject

    Agent only.

    0
    + Show child fields
    • kindstringrequired
      apiKeysession
    • idstringrequired
      0
Planobject

What a real call would do, from every check up to the first side effect. Nothing is reserved, sent, written or charged. The plan is stored for 15 minutes: send its planId with the real call to run exactly what was reviewed (409 PLAN_STALE with a new plan if anything bound changed or it expired).

  • operationIdstringrequired
    0
  • classstringrequired

    Safety class: decides scope, approval, caps and enforcement.

    readwritespendexternal_writesend
  • identityIdstring | nullrequired
    0
  • targetsobjectrequired
    0
    + Show child fields
    • totalintegerrequired
      0
    • wouldRunintegerrequired
      0
    • wouldSkiparray of objectrequired
      0
      + Show child fields
      • reasonstringrequired
        0
      • countintegerrequired
        0
      • samplearray of stringrequired
        0
  • creditsobjectrequired
    0
    + Show child fields
    • estimatedMinnumberrequired
      0
    • estimatedMaxnumberrequired
      0
    • availablenumberrequired
      0
    • capRemainingnumber | nullrequired
      0
  • quotaobject | nullrequired

    LinkedIn sends: the daily budget the action spends (an estimate: warm-up, health and the identity's other sends move it; the send gate decides at send time). bucket is the daily limit's key, identityRemainingToday what the identity's account has left today, keyRemainingToday the key's, user's or agent's daily sends left (null: uncapped), wouldDefer the targets that would wait for a later day, firstSlotAt / lastSlotAt when the first and last of them would go (ms; null past 7 days). Null for other operations.

    0
    + Show child fields
    • bucketstringrequired
      0
    • identityRemainingTodaynumberrequired
      0
    • keyRemainingTodaynumber | nullrequired
      0
    • wouldDefernumberrequired
      0
    • firstSlotAtnumber | nullrequired
      0
    • lastSlotAtnumber | nullrequired
      0
  • approvalobjectrequired
    0
    + Show child fields
    • requiredbooleanrequired
      0
    • reasonstring | nullrequired
      key_modeoperation_floorover_thresholdagentrequestedidentity_owner
  • writesobjectrequired
    0
  • previewarray of anyrequired

    The first targets that would run (at most 5).

    0
  • planIdstringrequired

    Valid until expiresAt, for the principal that made the dry run only.

    pattern ^plan_[0-9a-f]{48}$
  • expiresAtnumberrequired

    When the plan expires (epoch milliseconds).

    0
ResponseMetaobject

Metadata on every success response.

  • requestIdstringrequired
    0
  • creditsCreditsMetarequired
    0
  • Cursor pagination. hasMore is the only end signal; pages may be short.

    0
  • dryRunboolean

    True only on a dry-run response (action operations).

    0
CreditsMetaobject
  • usednumberrequired

    Credits charged by this request. Reads are free.

    0
  • balancenumber
    0
  • estimatednumber

    Dry run only (action operations).

    0
  • availablenumber

    Dry run only (action operations).

    0
  • reservationIdstring | null

    Async operations only; the job settles this reservation.

    0
PageMetaobject

Cursor pagination. hasMore is the only end signal; pages may be short.

  • nextCursorstring | nullrequired
    0
  • hasMorebooleanrequired
    0
  • limitintegerrequired
    min 1max 200
ActionTargetEnrichRecordsobject
EnrichPersonRecordobject
  • linkedinUrlstring

    The person's public LinkedIn profile URL (/in/...).

    max length 500
  • firstNamestring
    max length 200
  • lastNamestring
    max length 200
  • companystring
    max length 200
  • domainstring
    max length 200
EnrichWorkEmailInputobject
  • providersarray of string

    The waterfall, in order (default blitzapi, fullenrich, apollo, zoominfo). FullEnrich, Apollo and ZoomInfo run only with the workspace's own connected keys.

    blitzapifullenrichapollozoominfomin items 1max items 4
EnrichContactOutputobject
  • contactstring

    Write the found value onto a contact target: fillEmpty (default) only when it has none, overwrite always, skip never.

    skipfillEmptyoverwrite
EnrichMobilePhoneInputobject
  • providersarray of string

    The providers (only blitzapi today).

    blitzapimin items 1max items 1
AiGenerateMessageInputobject
  • channelstringrequired
    linkedinemail
  • messageTypestringrequired
    connection_requestfirst_messagefollow_upre_engagementpost_commentmeeting_request
  • customPromptstring
    max length 4000
  • stylestring
    friendlydirectconsultativechallenger
  • sequenceIdstring

    A sequence of this workspace, for its context.

    0
AiIcebreakerInputobject
  • typestring
    connection_requestfirst_messagefollow_upactivity_hookauto
  • stylestring
    friendlydirectconsultativechallenger
  • channelstring
    linkedin_dmlinkedin_inmailemail
  • customInstructionsstring
    max length 4000
AiSubjectInputobject
  • promptstringrequired

    What the subject line should do.

    min length 1max length 2000
  • bodystring

    The email body the subject goes with.

    max length 4000
ActionTargetWebQueryRecordsobject
  • kind"records"required
    0
  • recordsarray of WebQueryRecordrequired
    min items 1max items 100
WebQueryRecordobject
  • querystringrequired
    min length 1max length 300
ResearchWebInputobject
  • limitinteger
    min 1max 10
  • includeDomainsarray of string
    max items 10
  • timeRangestring
    dayweekmonthyear
ActionTargetPageUrlRecordsobject
  • kind"records"required
    0
  • recordsarray of PageUrlRecordrequired
    min items 1max items 100
PageUrlRecordobject
  • urlstringrequired
    max length 2000
ActionTargetCompanyDomainRecordsobject
CompanyDomainRecordobject
  • domainstringrequired

    The company's domain or website URL.

    max length 253
ActionTargetCompanyNameRecordsobject
  • kind"records"required
    0
  • recordsarray of CompanyNameRecordrequired
    min items 1max items 100
CompanyNameRecordobject
  • companyNamestringrequired
    min length 1max length 200
  • companyDomainstring
    max length 253

← All operations