Reference
Every listener route, body field, mentions filter, refused name and error on one page
This page lists everything a listener takes and returns. To get started, read the overview and run the quickstart first.
curl "https://www.socialcrawl.dev/v1/listening/streams?status=active" \
-H "x-api-key: YOUR_API_KEY"Routes
| Route | What it does |
|---|---|
POST /v1/listening/streams?dry_run=1 | Prices and checks a listener body. Costs 0 credits and creates nothing |
POST /v1/listening/streams | Creates a listener |
GET /v1/listening/streams | Lists your listeners, filtered by status, name or client |
GET /v1/listening/streams/{id} | Reads one listener |
PATCH /v1/listening/streams/{id} | Changes a listener |
POST /v1/listening/streams/{id}/pause | Pauses a listener |
POST /v1/listening/streams/{id}/resume | Resumes a listener |
DELETE /v1/listening/streams/{id} | Deletes a listener |
GET /v1/listening/streams/{id}/mentions | Reads the mentions a listener kept |
GET /v1/listening/streams/{id}/runs | Reads a listener's checks: what each one read, kept, billed and refunded |
POST /v1/listening/preview | Runs a listener body once and shows what its first check would keep. Billed like the same API calls. A preview of several pages can take 20 seconds or more, so set a client timeout of at least 60 seconds |
GET /v1/listening/usage | Credits and checks per client, listener, group or platform, as JSON or CSV |
New mentions also arrive as mention.created events on the events feed (GET /v1/events) and as signed pushes to your webhook endpoints. Every write (create, change, pause, resume, delete, preview) takes an Idempotency-Key header (idempotency). There is no estimate route: the dry run is the estimate.
Listener body
The create, the dry run, the preview and a change all take this body. Send exactly one of keywords, rule, groups or, for an account panel, accounts.
| Field | What it does | Default |
|---|---|---|
keywords | One group whose keywords are its searches, each matched as written. A keyword of several words is searched as a quoted phrase. At most 100 keywords of 500 characters each | |
rule | One group as boolean text: AND, OR, NOT, "quoted phrases" and brackets, up to 2,000 characters | |
groups | Several topics in one listener, at most 500. Each has a unique id and a rule or keywords, and can set its own context, exclude_terms, platforms, languages, country and tags | |
accounts | An account panel: up to 300 accounts, each platform:handle (reddit:nasa, youtube:@NASA) or a profile URL. Needs a topic and schedule.purpose | |
author_list_id | In place of accounts: the id of a list stored with POST /v1/prism/discover/inputs, read once when the listener is created | |
platforms | The platforms to watch. Google News is news, and x is accepted for twitter (lanes) | |
search_in | What to search on each platform: posts, comments on Reddit, blog and news on Naver | posts |
context | What kept posts must be about, naming the sense of an ambiguous keyword. 3 to 2,000 characters | |
schedule | How often the listener checks, its caps and its name. Required (below) | |
languages | ISO 639-1 codes. A post whose language is unknown is kept | |
country | ISO 3166-1 codes of the posts or authors to keep | |
exclude_country | ISO 3166-1 codes of the posts or authors to drop | |
unknown_country | keep or drop a post whose country is unknown when country or exclude_country is set | keep |
exclude_terms | Drops posts that contain any of these terms | |
exclude | Account keys (<platform>:<id>) or evidence ids to drop | |
sponsored | exclude drops posts marked as ads or paid partnerships, only keeps only those, keep turns the filter off | exclude |
relevance | filter drops posts the relevance check rejects, score keeps every match with its score, off does not check. The check is included in the price | filter |
relevance_definition | mentions keeps posts that name the topic, about keeps posts mainly about it | mentions |
comments | new_posts also reads the comments under each post the listener newly keeps, on Reddit (lanes) | off |
metadata | Up to 20 string labels for your own use, returned unchanged. client groups usage | |
draft | true saves the listener without running it | false |
new_listener | true creates a second listener even when an identical one exists | false |
Schedule
| Field | What it does | Default |
|---|---|---|
every | How often the listener checks: 30m, 1h, 3h, 6h, 1d or 7d. 30m works only when every chosen platform is read newest first | |
max_credits_per_month | The monthly cap in credits. A check that would pass it does not run, and the listener pauses until the next UTC month or a higher cap. An account panel can pass it by the second pages of one check (pricing). Required on a create made with an API key. A dry run without it still answers and recommends one | |
max_credits_per_run | The most one check may spend | data.estimate.max_credits_per_slot |
name | The listener's name, up to 120 characters | |
purpose | Required on an account panel: business, brand, creator or organisation | |
start_at | When the first check fires instead of at create, at most 90 days ahead |
An account holds up to 50 listeners. Schedules and months are in UTC.
Mentions route
GET /v1/listening/streams/{id}/mentions takes these filters. Pages are read with cursor: send the pagination.next_cursor of the page before until pagination.has_more is false.
| Filter | What it keeps |
|---|---|
since, until | Posts published at or after, or before, this time |
seen_since, seen_until | Posts the listener first saw at or after, or before, this time |
group | Mentions of this group id. A group a change removed still reads for the 30-day keep. An id the listener never had answers a free 400 with allowed_values |
tag.{key} | Mentions of groups with this tag, for example tag.client=client-b |
platform | Mentions from this platform. x works as twitter. A name no listener can watch answers a free 400 with allowed_values |
language | Posts in this language code. See the note below the table |
record_type | post or comment |
parent_id | The comments under the post with this evidence.id |
judgment_status | judged, pending or unjudged |
limit | 1 to 500 per page, 100 by default |
format | evidence (every field), compact or text |
include | raw adds the platform's original item as evidence.raw |
A language filter is checked after each mention is opened, and a request scans at most 2,000 stored mentions. A page can therefore come back short, or empty, with pagination.has_more set to true. Keep paging with pagination.next_cursor while has_more is true, even when a page is short or empty.
Mentions page in the order they were stored: the oldest check first and, inside a check, the order the platform returned its posts. data.dropped counts list items the response check removed because they did not match the documented shape. It is not a count of posts the relevance judge dropped, so it can be 0 when a check's dropped on the runs route is not.
Names a listener does not take
These names answer a 400 not_offered, with docs_url pointing here and, where one exists, did_you_mean. Nothing is charged.
| Name sent | Send instead |
|---|---|
query | rule: a listener's boolean text. Discover's query is one phrase sent as written. |
rules | groups, each with an id and a rule or keywords |
refresh_interval_minutes | schedule.every |
budget | schedule.max_credits_per_month: divide a money budget by money_per_credit (pricing) |
match_in | Nothing: a listener matches a post's title and text together |
delivery.endpoint_ids | subject_ids on a webhook endpoint |
stream_id | subject_id on the events feed and webhook endpoints |
stream_ids | subject_ids on the events feed and webhook endpoints |
threads | Nothing: new comments of a known post are a Monitor with webhook_rows: "new" |
from: (in a rule) | accounts: an account panel of the accounts whose posts you want |
label, questions, sentiment and tz are not available yet and answer not_released. A listener's slots and months are UTC.
Errors
Each refusal is free and carries details.reason, details.fields and details.next_step. Change the field it names rather than retrying.
details.reason | Status | What to do | Reference |
|---|---|---|---|
invalid_param | 400 | Send the field or value in did_you_mean, allowed_values or suggested_value | INVALID_REQUEST |
conflicting_params | 400 | Drop one of the fields in details.fields | INVALID_REQUEST |
not_released | 400 | Drop the field, value or route | INVALID_REQUEST |
not_offered | 400 | Send the name in did_you_mean, or drop it (table above) | INVALID_REQUEST |
interval_below_lane_minimum | 400 | Pick an every from allowed_values, or drop the platform whose lane details.lane names | INVALID_REQUEST |
unsupported_operator | 400 | Use the rule in nearest | INVALID_REQUEST |
plan_limit | 400 | Send fewer groups, search terms or accounts, within limit | INVALID_REQUEST |
budget_below_one_check | 400 | Ask the user to approve suggested_value, then send it in field | INVALID_REQUEST |
prohibited_use | 400 | Do not rephrase to pass. A dry run reports the verdict in data.screen instead; a create or a change refuses it | INVALID_REQUEST |
unknown_stream | 404 | The listener belongs to another key or does not exist. List your key's listeners | STREAM_NOT_FOUND |
stream_deleted, resume_from_dashboard | 409 | Create a new listener. A listener stopped on a revoked key cannot be resumed with an API key, so create a new one with an active key | STREAM_STATE_CONFLICT |
judge_unavailable | 503 | Retry after Retry-After. A dry run never answers it: when the use screen cannot run, data.screen.result is unavailable | SERVICE_UNAVAILABLE |
A few answers are not refusals of the body:
402INSUFFICIENT_CREDITSorKEY_BUDGET_EXCEEDEDon a preview whose first page the balance or the key's credit limit cannot pay. A listener's own checks never answer a 402: a check the balance cannot pay pauses the listener instead.413payload_too_largefor a body over the size limit. Split the groups across several listeners (PAYLOAD_TOO_LARGE).503store_unavailableorstore_timeoutwhen the listener store does not answer in time. Nothing is charged; retry the same call afterRetry-After(SERVICE_UNAVAILABLE).- The
Idempotency-Keyanswers on a write: a reused key with a different body, or a request still in progress (idempotency).
What does the use screen check?
The use screen checks what you declare in each group's rule or keywords and in context against the uses the Terms of Service section 7.2 forbid: monitoring a named private individual, a protest group or its organisers, or government or intelligence monitoring of people. On an account panel its word list also reads each entry, and schedule.purpose records what the panel watches. On a dry run it returns its verdict in data.screen with a warning and creates nothing either way. A create or a change that declares such a use is refused with prohibited_use, and so is a preview. The screen records what you declare and refuses declared uses; it is not a check of what a listener is later used for.
