Skip to main content

Signals API

The Signals API allows you to create, manage, and monitor your signals (saved searches).

Authentication Required

All API requests require authentication. See API Overview for details.

Response Format

Null fields are omitted from responses. For example, prompt is only included for keyword signals that have one configured, and query_identifier is only included for profile and company signals.

List Signals

Get signals in a workspace.

GET /api/signals

Query Parameters

ParameterTypeRequiredDescription
workspace_idstringYesThe workspace ID to list signals for
query_typestringNoFilter by signal type: search_keyword, user_profile, or company_profile. Returns all types if omitted
is_activatedbooleanNoFilter by activation status. Returns both active and inactive if omitted

Response

Returns an array of signal objects. Fields that are null are omitted.

[
{
"_id": "507f1f77bcf86cd799439012",
"name": "Brand Mentions",
"query": "lemlist OR \"heyreach\"",
"frequency": 24,
"is_activated": true,
"prompt": "Only mark relevant the posts that explicitly mention lemlist or HeyReach, the outreach tools",
"query_type": "search_keyword",
"created_at": "2024-01-10T08:00:00Z",
"updated_at": "2024-01-15T10:30:00Z"
},
{
"_id": "507f1f77bcf86cd799439013",
"name": "Follow Specific Person",
"query": "https://social.com/in/vearnold",
"frequency": 24,
"is_activated": true,
"query_type": "user_profile",
"query_identifier": "vearnold",
"created_at": "2024-01-12T09:00:00Z",
"updated_at": "2024-01-12T09:00:00Z"
},
{
"_id": "507f1f77bcf86cd799439014",
"name": "Company Posts",
"query": "https://social.com/company/example-corp",
"frequency": 24,
"is_activated": true,
"query_type": "company_profile",
"query_identifier": "12345678",
"created_at": "2024-01-13T10:00:00Z",
"updated_at": "2024-01-13T10:00:00Z"
}
]

Response Fields

FieldTypePresentDescription
_idstringAlwaysUnique signal identifier
namestringAlwaysSignal name
querystringAlwaysSearch query (keywords, profile URL, or company URL)
frequencyintegerAlwaysRun frequency in hours (default: 24)
is_activatedbooleanAlwaysWhether the signal is active
promptstringKeyword only, when configuredCustom AI filtering prompt
query_typestringAlwaysType of query: search_keyword, user_profile, company_profile
query_identifierstringProfile/company onlyUsername or company ID extracted from the URL
webhook_urlstringWhen configuredHTTPS URL for run completion callbacks
created_atstringAlwaysISO 8601 timestamp
updated_atstringAlwaysISO 8601 timestamp

Rate Limiting

  • 30 requests per minute per API key

Example Request

curl -H "X-API-Key: your_api_key_here" \
https://production.viacurrent.com/api/signals?workspace_id=507f1f77bcf86cd799439013

# Filter by type
curl -H "X-API-Key: your_api_key_here" \
"https://production.viacurrent.com/api/signals?workspace_id=507f1f77bcf86cd799439013&query_type=search_keyword"

# Only active signals
curl -H "X-API-Key: your_api_key_here" \
"https://production.viacurrent.com/api/signals?workspace_id=507f1f77bcf86cd799439013&is_activated=true"

Get Signal

Get detailed information about a specific signal.

GET /api/signals/{signal_id}

Path Parameters

ParameterTypeDescription
signal_idstringThe signal ID to retrieve

Response

Keyword signal:

{
"_id": "507f1f77bcf86cd799439012",
"name": "Brand Mentions",
"query": "lemlist OR \"heyreach\"",
"frequency": 24,
"is_activated": true,
"prompt": "Only mark relevant the posts that explicitly mention lemlist or HeyReach, the outreach tools",
"query_type": "search_keyword",
"created_at": "2024-01-10T08:00:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}

Profile signal:

{
"_id": "507f1f77bcf86cd799439013",
"name": "Follow Specific Person",
"query": "https://social.com/in/vearnold",
"frequency": 24,
"is_activated": true,
"query_type": "user_profile",
"query_identifier": "vearnold",
"webhook_url": "https://customer.com/callback",
"created_at": "2024-01-12T09:00:00Z",
"updated_at": "2024-01-12T09:00:00Z"
}

Rate Limiting

  • 60 requests per minute per API key

Example Request

curl -H "X-API-Key: your_api_key_here" \
https://production.viacurrent.com/api/signals/507f1f77bcf86cd799439012

Create Signal

Create a new signal in a workspace. The first run is triggered automatically — you don't need a separate API call to start it.

POST /api/signals

Request Body

FieldTypeRequiredDescription
workspace_idstringYesThe workspace ID to create the signal in
namestringYesSignal name (1-69 characters)
querystringYesSearch keywords, profile URL, or company URL (3-300 characters)
promptstringNoOptional custom AI filtering prompt for keyword signals (3-3000 characters). Ignored for profile/company signals
prompt_namestringNoOptional display name for the prompt (defaults to "AI filter"). Write-only — not returned in responses. Ignored for profile/company signals
webhook_urlstringNoHTTPS URL to receive run completion callbacks (max 1000 characters)
initial_windowstringNoFirst-run history window for profile/company signals: past_month (default), past_week, or none. Write-only — not returned in responses. Non-default values are rejected for keyword signals

The signal type (query_type) is automatically detected from the query string:

  • Keywordssearch_keyword — e.g. "lemlist OR \"heyreach\""
  • Profile URLuser_profile — e.g. "https://social.com/in/vearnold"
  • Company URLcompany_profile — e.g. "https://social.com/company/example"
AI Filtering (Keyword Signals Only)

Keyword signals can be created with only workspace_id, name, and query. Add prompt only when you want custom AI criteria for filtering posts.

For profile and company signals, prompt and prompt_name have no effect and are ignored — posts from the tracked profile or company are collected automatically.

Enrichment for Profile/Company Signals

When creating user_profile or company_profile signals, the API validates and enriches the profile synchronously. This means the request may take 5-15 seconds for these signal types. Keyword signals are instant.

First Run Window (Profile/Company Signals Only)

initial_window controls how much historical content the first run backfills for user_profile and company_profile signals. Use past_month to include roughly the last month, past_week to include roughly the last week, or none to start from signal creation time without historical backfill.

This setting only changes the initial backfill window. Subsequent scheduled runs continue from the signal checkpoint. Keyword signals do not use this setting; sending past_week or none with a keyword query returns a validation error.

Run Lifecycle

Signals run automatically on a ~24-hour schedule:

  1. First run starts immediately when the signal is created
  2. Subsequent runs are triggered automatically every ~24 hours

For profile/company signals, the first run honors initial_window when deciding how much historical content to fetch.

There is no endpoint to manually trigger additional runs. Use Run Status to poll for completion, or provide a webhook_url to receive a callback when each run finishes.

Response

Returns 201 Created with the signal object and initial run info:

{
"_id": "507f1f77bcf86cd799439012",
"name": "Brand Mentions",
"query": "lemlist OR \"heyreach\"",
"frequency": 24,
"is_activated": true,
"prompt": "Only mark relevant the posts that explicitly mention lemlist or HeyReach, the outreach tools",
"query_type": "search_keyword",
"webhook_url": "https://customer.com/callback",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z",
"run": {
"run_id": "507f1f77bcf86cd799439099",
"status": "queued"
}
}

Rate Limiting

  • 6 requests per minute per API key

Example Requests

Keyword Signal (optional custom filtering)

curl -X POST https://production.viacurrent.com/api/signals \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"workspace_id": "507f1f77bcf86cd799439013",
"name": "Brand Mentions",
"query": "lemlist OR \"heyreach\"",
"prompt": "Only mark relevant the posts that explicitly mention lemlist or HeyReach, the outreach tools",
"webhook_url": "https://customer.com/callback"
}'

Profile Signal

curl -X POST https://production.viacurrent.com/api/signals \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"workspace_id": "507f1f77bcf86cd799439013",
"name": "Follow Arnold",
"query": "https://social.com/in/vearnold",
"webhook_url": "https://customer.com/callback",
"initial_window": "past_week"
}'

Company Signal

curl -X POST https://production.viacurrent.com/api/signals \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"workspace_id": "507f1f77bcf86cd799439013",
"name": "Acme Corp Posts",
"query": "https://social.com/company/acme-corp",
"webhook_url": "https://customer.com/callback",
"initial_window": "none"
}'

Run Status

Get the status of the latest run for a signal. Use this to poll for completion after creating a signal, or to check the status of the latest scheduled run.

GET /api/signals/{signal_id}/run

Path Parameters

ParameterTypeDescription
signal_idstringThe signal to check

Response

{
"signal_id": "507f1f77bcf86cd799439012",
"run_id": "507f1f77bcf86cd799439099",
"status": "running",
"started_at": "2025-01-15T10:30:00Z"
}

Response Fields

FieldTypePresentDescription
signal_idstringAlwaysThe signal this run belongs to
run_idstringAlwaysUnique run identifier
statusstringAlwaysOne of: queued, pending, running, success, success_with_warnings, failed, timed_out, cancelled
started_atstringAfter startISO 8601 timestamp when the run started
completed_atstringAfter completionISO 8601 timestamp when the run finished
duration_msintegerAfter completionTotal run duration in milliseconds
errorstringOn failureError message if the run failed
Polling Strategy

Poll every 10-30 seconds. Most runs complete within 2-5 minutes. Once status is one of success, success_with_warnings, failed, timed_out, or cancelled, the run is finished and you can fetch the results via the Posts API or Engagers API.

Returns 404 Not Found if the signal has never been run.

Rate Limiting

  • 60 requests per minute per API key

Example: Create Signal and Poll Until Complete

import httpx
import time

API_KEY = "your_api_key_here"
BASE = "https://production.viacurrent.com/api"
WORKSPACE_ID = "507f1f77bcf86cd799439013"

headers = {"X-API-Key": API_KEY}

# 1. Create signal (first run starts automatically)
create_response = httpx.post(
f"{BASE}/signals",
headers=headers,
json={
"workspace_id": WORKSPACE_ID,
"name": "Brand Mentions",
"query": 'lemlist OR "heyreach"',
"prompt": "Only mark relevant the posts that explicitly mention lemlist or HeyReach, the outreach tools"
},
)
signal = create_response.json()
signal_id = signal["_id"]
print(f"Signal created: {signal_id}, run: {signal['run']['run_id']}")

# 2. Poll until the first run completes
terminal_statuses = {"success", "success_with_warnings", "failed", "timed_out", "cancelled"}

while True:
time.sleep(15)
status_response = httpx.get(
f"{BASE}/signals/{signal_id}/run",
headers=headers,
)
run = status_response.json()
print(f" Status: {run['status']}")

if run["status"] in terminal_statuses:
break

# 3. Fetch results
if run["status"] in ("success", "success_with_warnings"):
posts = httpx.get(
f"{BASE}/posts",
headers=headers,
params={"workspace_id": WORKSPACE_ID, "signal_ids": signal_id},
).json()
print(f"Got {len(posts['items'])} posts")

Deactivate Signal

Pause a signal. It will stop running on its schedule until reactivated. The signal and its collected data remain accessible.

PUT /api/signals/{signal_id}/deactivate

Path Parameters

ParameterTypeDescription
signal_idstringThe signal to deactivate

Response

Returns the updated signal object with is_activated: false.

{
"_id": "507f1f77bcf86cd799439012",
"name": "Brand Mentions",
"query": "lemlist OR \"heyreach\"",
"frequency": 24,
"is_activated": false,
"prompt": "Only mark relevant the posts that explicitly mention lemlist or HeyReach, the outreach tools",
"query_type": "search_keyword",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-20T14:00:00Z"
}

Rate Limiting

  • 6 requests per minute per API key

Example Request

curl -X PUT https://production.viacurrent.com/api/signals/507f1f77bcf86cd799439012/deactivate \
-H "X-API-Key: your_api_key_here"

Activate Signal

Reactivate a paused signal. It will resume running on its schedule.

PUT /api/signals/{signal_id}/activate

Path Parameters

ParameterTypeDescription
signal_idstringThe signal to activate

Response

Returns the updated signal object with is_activated: true.

{
"_id": "507f1f77bcf86cd799439012",
"name": "Brand Mentions",
"query": "lemlist OR \"heyreach\"",
"frequency": 24,
"is_activated": true,
"prompt": "Only mark relevant the posts that explicitly mention lemlist or HeyReach, the outreach tools",
"query_type": "search_keyword",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-20T15:00:00Z"
}

Rate Limiting

  • 6 requests per minute per API key

Example Request

curl -X PUT https://production.viacurrent.com/api/signals/507f1f77bcf86cd799439012/activate \
-H "X-API-Key: your_api_key_here"

Delete Signal

Permanently delete a signal. Posts and engagers collected by this signal remain accessible.

DELETE /api/signals/{signal_id}

Path Parameters

ParameterTypeDescription
signal_idstringThe signal to delete

Response

Returns 204 No Content with an empty body.

Rate Limiting

  • 6 requests per minute per API key

Example Request

curl -X DELETE https://production.viacurrent.com/api/signals/507f1f77bcf86cd799439012 \
-H "X-API-Key: your_api_key_here"

Use Cases

Get signal IDs for filtering posts

# 1. List all signals
curl -H "X-API-Key: your_api_key_here" \
https://production.viacurrent.com/api/signals?workspace_id=507f1f77bcf86cd799439013

# 2. Use signal IDs to filter posts
curl -H "X-API-Key: your_api_key_here" \
"https://production.viacurrent.com/api/posts?workspace_id=507f1f77bcf86cd799439013&signal_ids=507f1f77bcf86cd799439012,507f1f77bcf86cd799439015"

Get engagers for a profile signal

Signals with query_type of user_profile or company_profile have engagers (people who interacted with the tracked profile's posts).

# Get engagers for a profile signal
curl -H "X-API-Key: your_api_key_here" \
"https://production.viacurrent.com/api/engagers/signal/507f1f77bcf86cd799439013?workspace_id=507f1f77bcf86cd799439013&page=1&page_size=100"

Error Responses

400 Bad Request

{
"detail": "Invalid workspace_id format"
}

403 Forbidden

On create — workspace signal limit reached:

{
"detail": "workspace_signal_limit_reached"
}

On read/update/delete — signal doesn't belong to your workspace:

{
"detail": "signal_not_in_workspace"
}

404 Not Found

{
"detail": "Signal not found"
}

429 Too Many Requests

{
"detail": "Rate limit exceeded"
}

Full API Workflow

The complete API-only workflow to create a signal and consume results:

  1. Create a signal → POST /api/signals (first run starts automatically)
  2. Wait for results:
    • Option A: PollGET /api/signals/{id}/run every 10-30s until status is terminal
    • Option B: Webhook → provide a webhook_url when creating the signal; you'll receive a POST when each run completes
  3. Fetch resultsPosts API and/or Engagers API
  4. Ongoing — the signal runs automatically every ~24 hours. Use polling or webhooks to know when new results are ready.
  5. Managedeactivate/activate to pause/resume, or delete to remove permanently.

Run Completion Callback

If you provide a webhook_url when creating a signal, we'll POST to that URL every time a run completes — including the auto-triggered first run and all subsequent scheduled runs.

Not the same as Webhooks

This is a lightweight callback that notifies you when a signal run finishes. It does not deliver posts or engagers — you still fetch those via the Posts API or Engagers API. For automatically pushing collected data to external platforms (Slack, n8n, etc.), see Webhooks.

Payload

The callback payload matches the Run Status response:

POST https://customer.com/callback
Content-Type: application/json

{
"signal_id": "507f1f77bcf86cd799439012",
"run_id": "507f1f77bcf86cd799439099",
"status": "success",
"started_at": "2025-01-15T10:30:00Z",
"completed_at": "2025-01-15T10:33:45Z",
"duration_ms": 225000
}

Delivery

  • Timeout: 5 seconds per attempt
  • Retries: 1 retry after 30 seconds on failure
  • URL must be HTTPS
tip

You can use webhooks and polling together. The webhook notifies you immediately, and polling serves as a fallback if the webhook delivery fails.

Next Steps

Once you have signal IDs, you can: