Skip to content

API reference

Every endpoint a workspace key can reach

19 operations across 18 paths, generated from the server’s own route table: signals, accounts, listeners, pipeline, collections and exports. Each one carries the permission it needs and a request you can paste into a terminal.

Authenticate every request with Authorization: Bearer op_live_…. Mint a key in workspace settings and tick only the permissions it needs: a key always acts as a member, so a leaked one can read signals and move deals but can never create a listener, change billing, or mint another key.

Each example is the smallest request the document describes, with the real host and a placeholder secret. Replace anything in SHOUT_CASE and the braced segments of a path, and the call is one you can run.

6 of them are marked body not documented: those operations may take a JSON body that /openapi.json does not describe yet, so their example sends none and says so rather than presenting a command that may answer 400.

Operations are listed by path. A route the server mounts without a scope is absent from this page, because no key can call it — those are session-only, and documenting them would describe an interface you cannot reach.

GET /v1/accounts

List accounts

Requires accounts:read

Companies Openpulse has found signals about, cursor-paginated. One row per company rather than per post, which is usually the shape a sales question wants.

Requires a plan that includes account intelligence; a workspace without it gets a 403 naming the plan rather than an empty list.

ParameterInDescription
limitqueryPage size, 1-100.
cursorquerynextCursor from the previous page.
ownerqueryOnly accounts assigned to this member.
regionqueryOnly accounts in this region.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/accounts' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

GET /v1/accounts/{key}

Get one account

Requires accounts:read

Everything known about one company: its signals, its owner and its region.

ParameterInDescription
keyrequiredpathThe namespaced account key, e.g. d:acme.com for a domain. Percent-encode it: the : is part of the key, not a separator.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/accounts/{key}' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

POST /v1/collections

Create a list

Requires collections:write

A named list to save signals into, shared across the workspace.

Example request · body not documented
curl -X POST 'https://api.openpulse.cloud/v1/collections' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

The document declares no request body for this operation, so the example sends none. If the handler requires one, the call answers 400 until /openapi.json describes the shape.

GET /v1/content/ideas/{id}/export.zip

Download an idea's content as a zip

Requires export:read

Every piece written for one content idea, plus its assets, as a zip archive.

ParameterInDescription
idrequiredpathThe id of the resource.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/content/ideas/{id}/export.zip' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

GET /v1/exports/accounts.csv

Export accounts as CSV

Requires export:read

Streams the accounts matching the filters. A key's export is always filtered to what it may read: there is no unscoped dump, because a key is never an admin.

ParameterInDescription
ownerqueryOnly accounts assigned to this member.
regionqueryOnly accounts in this region.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/exports/accounts.csv' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

GET /v1/exports/pipeline.csv

Export the pipeline as CSV

Requires export:read

Streams the deals matching the filters, with their stages and values.

ParameterInDescription
stagequeryOnly deals in this stage.
openquerytrue for open stages only.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/exports/pipeline.csv' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

GET /v1/exports/signals.csv

Export signals as CSV

Requires export:read

Streams the signals matching the filters. Counts against the workspace's export quota; the response is a stream, so read it rather than buffering it whole.

ParameterInDescription
listenerIdqueryOnly this listener's signals.
classificationqueryIntent label; valid values depend on the listener's mode.
maxAgeDaysqueryOnly signals seen within this many days.
sourcequeryPlatform the signal came from.
themequeryOnly signals carrying this theme.
qqueryFree-text search over the signal's title and summary. Matches whole words, with stemming: report finds reporting, repo does not. Truncated past 120 characters.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/exports/signals.csv' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

GET /v1/listeners

List listeners

Requires listeners:read

Every listener in the workspace, newest first, cursor-paginated. Each item carries its mode, its objective, its schedule and a count of the signals it has kept.

A key can read listeners and never change one: creating, editing and deleting a listener spends money on a recurring basis and stays with workspace admins.

ParameterInDescription
limitqueryPage size, 1-100.
cursorquerynextCursor from the previous page.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/listeners' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

GET /v1/listeners/{id}

Get one listener

Requires listeners:read

One listener with its full configuration — keywords, exclusions, per-source queries, sensitivity and schedule — plus its current scheduler state.

An id belonging to another workspace is indistinguishable from one that does not exist: both answer 404.

ParameterInDescription
idrequiredpathThe id of the resource.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/listeners/{id}' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

POST /v1/listeners/analyse-website

Derive a listener plan from a website

Requires listeners:analyse

Crawls a website and returns a complete listener plan: keywords, exclusions, per-source queries, and a mode-specific profile — target roles, rival names and pain vocabulary, or place categories. Everything is editable before it runs.

This is the step every competing product replaces with an empty keyword box.

Rate limited to 5 calls an hour per key, and counted against the workspace's monthly allowance. An unreadable website answers 422 with website_unreadable rather than an error: the caller is asked to describe the business instead. Nothing is counted against the allowance unless the analysis succeeded.

To recover from a website_unreadable 422, resend the same request with description filled in and acceptLimited: true: the plan is then generated from the description instead of a crawl.

Example request
curl -X POST 'https://api.openpulse.cloud/v1/listeners/analyse-website' \
  -H 'Authorization: Bearer op_live_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "companyName": "YOUR_COMPANY_NAME",
    "website": "https://example.com",
    "objective": "find_customers",
    "sources": [
      "x"
    ]
  }'

POST /v1/notes

Write a note

Requires collections:write

Attaches a note to a signal, an account or a deal.

Example request · body not documented
curl -X POST 'https://api.openpulse.cloud/v1/notes' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

The document declares no request body for this operation, so the example sends none. If the handler requires one, the call answers 400 until /openapi.json describes the shape.

GET /v1/pipeline

List deals

Requires pipeline:read

Every deal in the workspace's pipeline with its stage, cursor-paginated. The board shows all columns at once by fetching pages until they are exhausted; do the same rather than assuming one response is the whole pipeline.

ParameterInDescription
limitqueryPage size, 1-100.
cursorquerynextCursor from the previous page.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/pipeline' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

POST /v1/pipeline

Add a deal

Requires pipeline:write

Creates one deal, optionally from the signal that prompted it.

Example request · body not documented
curl -X POST 'https://api.openpulse.cloud/v1/pipeline' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

The document declares no request body for this operation, so the example sends none. If the handler requires one, the call answers 400 until /openapi.json describes the shape.

PATCH /v1/pipeline/{id}

Update a deal

Requires pipeline:write

Moves a deal between stages, or edits its value, owner or notes. Partial: only the fields present are changed.

ParameterInDescription
idrequiredpathThe id of the resource.
Example request · body not documented
curl -X PATCH 'https://api.openpulse.cloud/v1/pipeline/{id}' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

The document declares no request body for this operation, so the example sends none. If the handler requires one, the call answers 400 until /openapi.json describes the shape.

POST /v1/pipeline/bulk

Add several deals at once

Requires pipeline:write

One request rather than a loop, which is what an agent working from a list of signals should reach for: the per-deal writes are applied together and the response reports each outcome.

Example request · body not documented
curl -X POST 'https://api.openpulse.cloud/v1/pipeline/bulk' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

The document declares no request body for this operation, so the example sends none. If the handler requires one, the call answers 400 until /openapi.json describes the shape.

GET /v1/pipeline/roi

Pipeline return over a window

Requires pipeline:read

What the pipeline sourced from Openpulse signals is worth over the window: deals opened, deals won, and value. The answer to 'is this paying for itself'.

ParameterInDescription
daysqueryWindow length in days.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/pipeline/roi' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

GET /v1/results

List signals

Requires signals:read

Kept signals across the workspace, newest first, cursor-paginated. A signal is one public post, job posting or review that a listener judged relevant, with its score and the reasoning behind it.

classification values differ per listener mode: filtering by one from the wrong mode returns an empty page rather than an error, which reads as 'nothing found' and is not. Pass listenerId to scope the filter to a listener whose mode you know.

ParameterInDescription
listenerIdqueryOnly signals from this listener.
limitqueryPage size, 1-100.
cursorquerynextCursor from the previous page.
maxAgeDaysqueryOnly signals seen within this many days.
classificationqueryIntent label. Valid values depend on the listener's mode.
sourcequeryPlatform the signal came from.
themequeryOnly signals carrying this theme.
qqueryFree-text search over the signal's title and summary. Matches whole words, with stemming: report finds reporting, repo does not. Truncated past 120 characters.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/results' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

GET /v1/results/stats

Count signals in a window

Requires signals:read

Totals for the window, counted in the database rather than over a page, so the figures describe every signal rather than the ones that fit in one response. Use this instead of paging through /v1/results to answer 'how many'.

ParameterInDescription
listenerIdqueryOnly count this listener's signals.
maxAgeDaysqueryWindow in days. Defaults to the workspace's retention.
sourcequeryPlatform the signal came from.
themequeryOnly signals carrying this theme.
qqueryFree-text search over the signal's title and summary. Matches whole words, with stemming: report finds reporting, repo does not. Truncated past 120 characters.
Example request
curl -X GET 'https://api.openpulse.cloud/v1/results/stats' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

POST /v1/signals/{id}/save

Save a signal to a list

Requires collections:write

Adds one signal to a list. Idempotent: saving a signal already in the list is not an error and does not duplicate it.

ParameterInDescription
idrequiredpathThe id of the resource.
Example request · body not documented
curl -X POST 'https://api.openpulse.cloud/v1/signals/{id}/save' \
  -H 'Authorization: Bearer op_live_YOUR_KEY'

The document declares no request body for this operation, so the example sends none. If the handler requires one, the call answers 400 until /openapi.json describes the shape.

Two rate limits, reported two ways. The burst limit on website analysis is per key and answers 429 with a Retry-After header. The monthly analysis allowance is per workspace and answers 429 with readyAt, used and allowed in the body, no header. Something unclear or wrong? Email support@openpulse.cloud.