mySDRDocs

API reference

Create a monitor

A standing keyword monitor. Creating it is free. Each later run charges per new mention it delivers. schedule hourly is 400. A keyword is a string, or an object with keyword and the settings below. A keyword of more than one word is searched as that phrase. The search only uses the keywords. The settings are checked on the text of each post it found, before the relevance check, so they can only drop posts. A post becomes a mention when its text has an active keyword and it passes that keyword's settings. A post whose text has no active keyword is dropped, because LinkedIn also matches names. The word lists match whole words, in any case and with or without accents.

POSThttps://mysdr.app/api/v1/monitors
View Markdown

Authentication

Send Authorization: Bearer gtk_…. Create the key under Connect assistant → API keys. A missing, invalid or revoked key is 401. A valid key while this API is not enabled for your organization answers 403 api_not_enabled, with what the key can do instead. Every response includes mySDR-Api-Version, mySDR-Request-Id and Cache-Control: no-store, and a response to an accepted key also X-RateLimit-* (so not a 401, a 405, an OPTIONS or a 404 for an unknown path).

Headers

  • Idempotency-Key string — Optional. The same key and the same body replay the monitor that was created. The same key with a different body is 409 idempotency_conflict.

Body parameters

  • name string · required — 1 to 120 characters.
  • keywords array · required — 1 to 10 keywords: strings, or objects with the fields below.
  • keywords[].keyword string · required — The word or phrase, 2 to 100 characters.
  • keywords[].context string | null — Up to 200 characters for the relevance check, such as what the keyword means for you.
  • keywords[].tag string | null — A label for the keyword. One of: own_brand, competitor, industry_term.
  • keywords[].exact_match boolean — Defaults to true: the keyword must stand on its own. A domain (acme.com), handle (@acme), hashtag (#acme, or #AcmeAnalytics for Acme Analytics) or possessive (acme's) counts. A plural (acmes) does not. A space and a hyphen between words count the same. false: the keyword may also sit inside a longer word (acmes, support.acme.io).
  • keywords[].case_sensitive boolean — Defaults to false: any case, with or without accents. true: only as written (RAG, not rag). The word lists always ignore case.
  • keywords[].also_include_any string[] — Up to 10 words. The post must also use at least one of them.
  • keywords[].also_include_all string[] — Up to 10 words. The post must also use all of them.
  • keywords[].exclude_words string[] — Up to 50 words. A post that uses one of them is dropped.
  • keywords[].exclude_wildcards string[] — Up to 50 patterns. A post with a word that matches one is dropped. A pattern starts at the start of a word, and * stands for any characters within that word: beta.* drops beta.2 and beta.acme.io.
  • keywords[].exclude_authors string[] — Up to 100 LinkedIn profile URLs. Posts by these people are dropped.
  • keywords[].paused boolean — Defaults to false. A paused keyword is not searched and counts for no post.
  • schedule string — Defaults to daily. hourly is not available yet (400). One of: daily, hourly.
  • min_relevance string — Defaults to medium. One of: high, medium, low.
  • tags string[] — Tags to keep, such as own_brand_mention, competitor_mention, buy_intent.
  • webhook_endpoint_id null — A monitor sends no webhooks: an id is 400. Read new mentions with GET /mentions?monitor_id=… instead (free).
  • max_credits_per_day integer | null — Daily credit cap for the runs, at least the price of one mention: a lower cap is 400. A run also stops at the organization’s daily credit limit.

Response

  • id string · required — Monitor id, mon_….
  • object string · required — Always monitor. One of: monitor.
  • name string · required — The name you gave it.
  • status string · required — active, paused, or deleted after DELETE. One of: active, paused, deleted.
  • schedule string · required — daily. hourly is not available yet. One of: daily, hourly.
  • keywords object[] · required — Each keyword with all its settings, exact_match and case_sensitive included, and paused.
  • min_relevance string · required — high, medium or low. One of: high, medium, low.
  • max_credits_per_day integer | null — Daily cap, or null for none.
  • credits_today integer · required — Credits this monitor spent today (Europe/Brussels calendar day).
  • credits_charged integer · required — Credits charged so far.
  • next_run_at string | null · required — When the next run starts; null while the monitor is paused or deleted.
  • last_run object | null · required — What the last run did: at, mentions_delivered, credits_charged and stopped_by. stopped_by is null when the run read everything it found, or max_credits_per_day (the monitor’s cap), daily_limit (the organization’s daily limit), balance (the wallet), or paused or deleted (the monitor was paused or deleted during the run, which stops the charging). A run that a cap or the balance stopped before it read anything shows 0 mentions with that reason. Null before the first run.
  • deleted_at string | null · required — When DELETE stopped the monitor.
  • mentions_readable_until string | null · required — For a deleted monitor: until when it and its mentions stay readable (30 days after DELETE).

Credits

Creating a monitor is free. A run charges 1 credit per new mention delivered. A run that finds nothing is free.

Errors

  • 400 invalid_request — A keyword is too short, or schedule is hourly.
  • 401 authentication_error — The Authorization header is missing, or the key is unknown or revoked.
  • 403 permission_error — API access is not part of your plan, or your account is suspended.
  • 403 api_not_enabled — The key is valid, but the Signals API or the Company API is not enabled for your organization yet. The error says what this key can do.
  • 429 rate_limit_error — More than 60 requests per minute, or more than 3 at the same time, on one key. Wait for the Retry-After header.
  • 500 internal_error — Something went wrong on our side.

Example

cURL

curl -X POST "https://mysdr.app/api/v1/monitors" \
  -H "Authorization: Bearer $MYSDR_API_KEY" \
  -H "Idempotency-Key: idem-1" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme mentions",
    "keywords": [
      {
        "keyword": "Acme Analytics",
        "tag": "own_brand",
        "exact_match": true,
        "exclude_words": [
          "vacancy"
        ],
        "exclude_authors": [
          "https://www.linkedin.com/in/jane-example"
        ]
      }
    ],
    "max_credits_per_day": 50
  }'

JavaScript

const response = await fetch('https://mysdr.app/api/v1/monitors', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.MYSDR_API_KEY}`,
    'Idempotency-Key': 'idem-1',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "name": "Acme mentions",
    "keywords": [
      {
        "keyword": "Acme Analytics",
        "tag": "own_brand",
        "exact_match": true,
        "exclude_words": [
          "vacancy"
        ],
        "exclude_authors": [
          "https://www.linkedin.com/in/jane-example"
        ]
      }
    ],
    "max_credits_per_day": 50
  })
});
const body = await response.json();

Python

import json
import os
import urllib.request

payload = {
  "name": "Acme mentions",
  "keywords": [
    {
      "keyword": "Acme Analytics",
      "tag": "own_brand",
      "exact_match": True,
      "exclude_words": [
        "vacancy"
      ],
      "exclude_authors": [
        "https://www.linkedin.com/in/jane-example"
      ]
    }
  ],
  "max_credits_per_day": 50
}

request = urllib.request.Request(
    "https://mysdr.app/api/v1/monitors",
    headers={
    "Authorization": f"Bearer {os.environ['MYSDR_API_KEY']}",
    "Idempotency-Key": "idem-1",
    "Content-Type": "application/json"
    },
    data=json.dumps(payload).encode(),
    method="POST",
)
with urllib.request.urlopen(request) as response:
    body = json.load(response)

Example response

{
  "id": "mon_01J9Z6P8C8V0K3W6T2N8R5M1XF",
  "object": "monitor",
  "name": "Acme mentions",
  "status": "active",
  "schedule": "daily",
  "credits_charged": 0
}