mySDRDocs

API reference

Find Companies Using a Technology

Returns up to limit companies (10 unless you say otherwise, at most 25) that use one of your technologies, with the evidence per company: how sure the match is, in how many job posts it appeared, and when it was first and last seen. A company counts only when the technology was in one of its job posts of the last 12 months, with medium or high confidence; older or weaker evidence is left out at no charge.

POSThttps://mysdr.app/api/v1/technologies/companies
View Markdown

technologies takes slugs or exact names (GET /technologies finds them); an unknown one is 400 with code unknown_technology and the closest slugs in suggestions. Narrow with countries, company_sizes and exclude_domains: the companies you already have, so you do not pay for them again.

The call waits for the result, usually a few seconds. For more companies, send next_cursor back as cursor with the same technologies, filters and limit: one chain never returns a company twice. The same request on the same day, from any key of your organization (upper or lower case does not matter), returns the same search again without charging twice; with your own Idempotency-Key header, that key decides instead.

Some technology names are also common words or job titles in job posts (Teamleader is also "team leader"). For those, notes says so: check the evidence (jobs_mentioning, last_seen_on) before you tell the user a company uses it.

Each company has an id (cmp_…) that POST /tables/companies saves to the user’s Companies table, and the whole result is in mySDR at dashboard_url. To find the people at these companies, use Search People with current_companies set to their linkedin_url.

Authentication

Send Authorization: Bearer gtk_…. Create the key under Connect assistant → API keys. This endpoint answers for every key with API access: it is not behind the Signals API or the Company API. A missing, invalid or revoked key is 401. Every response includes mySDR-Api-Version, mySDR-Request-Id and Cache-Control: no-store, and a response to an accepted key also X-RateLimit-*; every error has type, message, param and request_id.

Headers

  • Idempotency-Key string — Optional, 8 to 255 characters. The same key and body return the first result again for 24 hours, charged once; the same key with another body is 409 idempotency_conflict. Without it, the same body on the same day does the same.

Body parameters

  • technologies string[] · required — 1 to 5 technologies, by slug or exact name, e.g. ["hubspot"]. A company that uses any of them matches.
  • countries string[] — Up to 20 countries where the company is based: ISO 3166-1 alpha-2 codes (BE, NL; UK is read as GB) or English names. Empty means anywhere.
  • company_sizes string[] — Headcount ranges of the company; empty means any size. One of: self-employed, 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+.
  • exclude_domains string[] — Up to 100 domains that never come back (a website or an email address works too): your customers, or companies you already have.
  • limit integer — How many companies to return at most, 1 to 25. Defaults to 10. You pay 3 credits per company returned, so this is also the most the call costs.
  • cursor string — The next_cursor of the previous response, with the same technologies, filters and limit.
  • max_credits integer — Stop before the call costs more than this: at most max_credits ÷ 3 companies. Below the price of one company the call is 402 max_credits_exceeded and nothing is searched.

Response

  • search_id string — The search behind this call (srch_…), shown in mySDR at dashboard_url. Reading it with GET /searches needs the Signals API; for more companies use next_cursor.
  • companies object[] — The companies, in each answer the strongest evidence first (highest confidence, then most job posts). A next page can hold stronger evidence than the last company of this one. See the fields below.
  • companies[].id string — Company id (cmp_…): POST /tables/companies saves it to the Companies table, for 30 days.
  • companies[].name / domain / linkedin_url string | null — The company. linkedin_url is what Search People takes in current_companies.
  • companies[].country_code string | null — ISO 3166-1 alpha-2 of the headquarters.
  • companies[].industry string | null — Industry.
  • companies[].technologies object[] — The evidence per technology you asked for: slug, name, confidence (low, medium or high: how sure the match is), first_seen_on and last_seen_on (the first and the last job post that mentioned it) and jobs_mentioning (in how many job posts).
  • companies[].observed_at string — When this evidence was fetched (ISO 8601).
  • companies[].credits_charged integer — What this call charged for it: 3, or 0 on a repeat of the same request.
  • total_count integer | null — How many companies match in total, as far as the data says.
  • has_more boolean — More companies match than this call returned.
  • next_cursor string | null — Send it back as cursor for the next companies; null when there are no more.
  • credits_used integer — Credits this call used: 0 on a repeat of the same request.
  • truncated_by string — Only when a cap returned fewer companies than limit. One of: max_credits, daily_limit.
  • sources string[] — Always ["job_postings"].
  • notes string[] — What was left out and why, in plain language.
  • dashboard_url string — These companies in mySDR (Companies, with the ones not saved yet marked).

Credits

3 credits per company returned; no companies, no credits. Errors and empty lookups are free. A call that spent credits puts that number in credits_used, in X-Credits-Used and in X-Credits-Charged. When the wallet can be read, the response also sends X-Credits-Remaining.

Errors

  • 400 invalid_request — The body is not valid JSON, a field is unknown or has the wrong type, or a value is not allowed.
  • 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.
  • 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.
  • 429 daily_limit_reached — The request could take your organization over its daily credit limit. The limit resets at midnight (Europe/Brussels).
  • 402 insufficient_credits — The credit balance is lower than this request could cost. Nothing was charged. Add credits, or send a smaller request. The error includes code, fix and a link to the credits docs.
  • 502 upstream_error — The data source did not answer. Retry later.
  • 503 service_unavailable — The API is temporarily unavailable. Retry later.
  • 500 internal_error — Something went wrong on our side.
  • 402 max_credits_exceeded — max_credits is lower than the credits of the first row, so nothing could be returned. Nothing was charged; raise max_credits or ask for fewer rows.
  • 409 idempotency_conflict — The Idempotency-Key was already used with another request body.
  • 409 idempotency_in_progress — The first request with this Idempotency-Key is still being processed. Wait for the Retry-After header.

Example

cURL

curl -X POST "https://mysdr.app/api/v1/technologies/companies" \
  -H "Authorization: Bearer $MYSDR_API_KEY" \
  -H "Idempotency-Key: idem-1" \
  -H "Content-Type: application/json" \
  -d '{
    "technologies": [
      "hubspot"
    ],
    "countries": [
      "BE"
    ],
    "company_sizes": [
      "51-200",
      "201-500"
    ],
    "limit": 2
  }'

JavaScript

const response = await fetch('https://mysdr.app/api/v1/technologies/companies', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.MYSDR_API_KEY}`,
    'Idempotency-Key': 'idem-1',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "technologies": [
      "hubspot"
    ],
    "countries": [
      "BE"
    ],
    "company_sizes": [
      "51-200",
      "201-500"
    ],
    "limit": 2
  })
});
const body = await response.json();

Python

import json
import os
import urllib.request

payload = {
  "technologies": [
    "hubspot"
  ],
  "countries": [
    "BE"
  ],
  "company_sizes": [
    "51-200",
    "201-500"
  ],
  "limit": 2
}

request = urllib.request.Request(
    "https://mysdr.app/api/v1/technologies/companies",
    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

{
  "search_id": "srch_01JB8X3KZQ7Y9C2V5N4T6R8W0M",
  "companies": [
    {
      "id": "cmp_01JB8X3M2P4Q6R8S0T2V4W6X8Y",
      "name": "Acme Analytics",
      "domain": "acme-analytics.example",
      "linkedin_url": "https://www.linkedin.com/company/acme-analytics",
      "country_code": "BE",
      "industry": "Software Development",
      "technologies": [
        {
          "slug": "hubspot",
          "name": "HubSpot",
          "confidence": "high",
          "first_seen_on": "2024-03-12",
          "last_seen_on": "2026-10-02",
          "jobs_mentioning": 14
        }
      ],
      "observed_at": "2026-10-25T09:12:04Z",
      "credits_charged": 3
    }
  ],
  "total_count": 312,
  "has_more": true,
  "next_cursor": "cur_eyJ2IjoxLCJzIjoic3JjaF8wMUpCOFgzS1pRN1k5QzJWNU40VDZSOFcwTSJ9",
  "credits_used": 3,
  "sources": [
    "job_postings"
  ],
  "notes": [],
  "dashboard_url": "https://mysdr.app/en/gtm/companies?search=srch_01JB8X3KZQ7Y9C2V5N4T6R8W0M"
}