SocialCrawl

Overview

What a listener is, what you can call today, which release brings the rest, and the names a listener does not take

A listener watches keywords or a boolean topic on the platforms you choose, on a schedule you set, and will deliver each new mention it finds. Listeners ship in LRel2a. Today you can price and validate one: POST /v1/listening/streams?dry_run=1 takes the same body a create will take, answers with the monthly cost in credits and money, costs 0 credits and creates nothing.

cURL
curl -X POST "https://www.socialcrawl.dev/v1/listening/streams?dry_run=1" \
  -H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" \
  -d '{"keywords": ["Acme", "Acme Cloud"], "platforms": ["reddit"], "schedule": {"every": "1h", "name": "Acme brand"}}'

The answer holds the listener as it would be stored, each group's rule as a tree and in words (read_back), the estimate at data.estimate, the per-lane plan at data.plan, the use screen's verdict at data.screen, warnings and next_step. The quickstart walks through a full answer, and pricing shows how the estimate is computed.

What is a listener?

A listener holds one or more groups, each a boolean rule or plain keywords, with an optional context that says which sense of an ambiguous keyword you mean. It also holds the platforms to watch and a required schedule:

JSON
{
  "groups": [
    { "id": "outage", "rule": "\"Globex Mobile\" AND (outage OR down OR \"no signal\")" },
    { "id": "pricing", "rule": "(\"Globex Mobile\" OR \"Globex Prepaid\") AND (price OR bill OR tariff)" }
  ],
  "platforms": ["youtube", "reddit"],
  "context": "Globex Mobile, the mobile network operator, and its Globex Prepaid plans. Not Globex Corporation or any other company named Globex.",
  "schedule": { "every": "1h", "max_credits_per_month": 15000, "name": "Client B: Globex Mobile" }
}

Top-level keywords or rule is the shorthand for one group. Send exactly one of keywords, rule and groups. schedule.every is one of 30m, 1h, 3h, 6h, 1d and 7d, and 30m works only when every chosen platform is read newest first (lanes). schedule.max_credits_per_month is a cap in credits, never money. The names are discover's wherever the meaning is the same, so a body you send to a discover schedule reads the same way here.

What ships when

Every route below is mounted today. A route of a later release answers a 400 not_released with details.release naming the release that brings it, and charges nothing. On the create route, next_step points at the dry run.

RouteWhat it doesRelease
POST /v1/listening/streams?dry_run=1Price and validate a listener; creates nothingLRel1, available now
POST /v1/listening/streamsCreate a listenerLRel2a
GET /v1/listening/streamsList your listenersLRel2a
GET /v1/listening/streams/{id}Read one listenerLRel2a
PATCH /v1/listening/streams/{id}Change a listenerLRel2a
POST /v1/listening/streams/{id}/pausePause a listenerLRel2a
POST /v1/listening/streams/{id}/resumeResume a listenerLRel2a
DELETE /v1/listening/streams/{id}Delete a listenerLRel2a
GET /v1/listening/streams/{id}/mentionsRead a listener's mentionsLRel2a
GET /v1/listening/streams/{id}/runsRead a listener's checksLRel2a
POST /v1/listening/previewRun a listener body once over the last 24 hoursLRel2b
GET /v1/listening/usageCredits and checks per client, listener or platformLRel2b

There is no estimate route: POST /v1/listening/estimate answers 404 with did_you_mean naming the dry run. LRel2a also adds the listener events to the events feed and webhook endpoints. Comments under matching posts arrive in LRel3, and panels of accounts filtered by a topic in LRel4.

Which call fits the job?

Until listeners ship, a recurring watch on a topic is a discover schedule, and the new posts of an account you already know are a Monitor with webhook_rows: "new". The dry run answers what a keyword or boolean topic listener would cost. Choosing endpoints holds the one routing rule for every standing watch.

Names a listener does not take

These names answer a 400 not_offered, with docs_url pointing at this page and, where one exists, did_you_mean. Nothing is charged.

Name sentSend instead
queryrule: a listener's boolean text. Discover's query is one phrase sent as written.
rulesgroups, each with an id and a rule or keywords
refresh_interval_minutesschedule.every
budgetschedule.max_credits_per_month: divide a money budget by money_per_credit (pricing)
match_inNothing: a listener matches a post's title and text together
delivery.endpoint_idssubject_ids on a webhook endpoint
stream_idsubject_id on the events feed and webhook endpoints
stream_idssubject_ids on the events feed and webhook endpoints
threadsNothing: new comments of a known post are a Monitor with webhook_rows: "new"

Some names belong to a later release and answer not_released naming it instead: accounts and schedule.purpose (LRel4), comments under matching posts (LRel3), label and questions (once their accuracy gate passes), sentiment (with label=stance) and tz (local-time schedules; 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.reasonStatusWhat to doReference
invalid_param400Send the field or value in did_you_mean, allowed_values or suggested_valueINVALID_REQUEST
conflicting_params400Drop one of the fields in details.fieldsINVALID_REQUEST
not_released400Drop the field, value or route, or wait for details.releaseINVALID_REQUEST
not_offered400Send the name in did_you_mean, or drop it (table above)INVALID_REQUEST
interval_below_lane_minimum400Pick an every from allowed_values, or drop the platform whose lane details.lane namesINVALID_REQUEST
unsupported_operator400Use the rule in nearestINVALID_REQUEST
plan_limit400Send fewer groups or search terms, within limitINVALID_REQUEST
budget_below_one_check400Ask the user to approve suggested_value, then send it in fieldINVALID_REQUEST
prohibited_use400Do not rephrase to pass. A dry run reports the verdict in data.screen instead; a create refuses it from LRel2aINVALID_REQUEST
judge_unavailable503Retry after Retry-After. A dry run never answers it: when the use screen cannot run, data.screen.result is unavailableSERVICE_UNAVAILABLE

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 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 from LRel2a, and a preview from LRel2b.

On this page