mySDRDocs

API reference

Reverse Email Lookup

Finds the person behind an email address, work or personal, and returns their full LinkedIn profile and their company: up to 25 addresses per call, each with its own entry in results, in the order you sent them.

POSThttps://mysdr.app/api/v1/person/reverse-email
View Markdown

A person found costs 1 credit. An address nobody matches, or a value that is not an email address, costs nothing. The same address twice in one call is looked up and charged once, and so is the same person behind two addresses.

The profile has the same fields as Enrich People. The company is the employer of the current position, plus the domain of the address when it is a work address; for the full company profile, send it to Enrich Companies. The address itself is not checked over SMTP: for a verified work email, use Enrich People with include_email.

Authentication

Send your API key as a Bearer token: Authorization: Bearer gtk_…. Create the key under Connect assistant → API keys. A missing, invalid or revoked key is 401, including while an API is closed. On an endpoint of the Signals API or the Company API, a valid key while that API is closed for your organization answers 403 api_not_enabled, with what the key can do instead; the other endpoints work with every key. 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); every error has type, message, param and request_id.

Body parameters

  • emails string[] · required — 1 to 25 email addresses, work or personal, e.g. jane@acme.example.
  • max_credits integer — Stop before the call costs more than this. An address is looked up only while a person still fits, at 1 credit, in the order you sent them; an address that finds nobody costs nothing and leaves the room to the next. Addresses left over are not looked up and get skipped.

Response

  • results object[] — One entry per address you sent, in the same order.
  • results[].input string — The address as you sent it.
  • results[].status string — matched (see person and company), not_found (nobody known with this address), invalid_email (not an email address), error (the lookup failed; nothing was charged, retry later) or skipped (max_credits left no room; not looked up). One of: matched, not_found, invalid_email, error, skipped.
  • results[].person object | null — The profile when the status is matched, with the fields of Enrich People (without email); otherwise null.
  • results[].company object | null — name and linkedin_url of the current employer (null when the profile shows none), and domain: the domain of the address when it is a work address, otherwise null. Null unless the status is matched.
  • results[].credits_charged integer — What this entry cost. An address you sent twice is charged on its first entry.
  • results[].save_input object — With a matched person: this person as one entry of leads for POST /tables/leads, with the address you sent as email (no email_status: the address was not checked).
  • results[].error object — With error and skipped: type (upstream_error or max_credits_exceeded) and message.
  • credits_used integer — Credits this call used.

Credits

1 credit per person found; nobody found costs nothing. 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).
  • 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 below the price of one lookup (1 credit). Nothing was looked up.

Example

cURL

curl -X POST "https://mysdr.app/api/v1/person/reverse-email" \
  -H "Authorization: Bearer $MYSDR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "emails": [
      "jane@acme-analytics.example",
      "nobody@example.com"
    ]
  }'

JavaScript

const response = await fetch('https://mysdr.app/api/v1/person/reverse-email', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.MYSDR_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    "emails": [
      "jane@acme-analytics.example",
      "nobody@example.com"
    ]
  })
});
const body = await response.json();

Python

import json
import os
import urllib.request

payload = {
  "emails": [
    "jane@acme-analytics.example",
    "nobody@example.com"
  ]
}

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

Example response

{
  "results": [
    {
      "input": "jane@acme-analytics.example",
      "status": "matched",
      "person": {
        "linkedin_url": "https://www.linkedin.com/in/jane-example",
        "linkedin_id": "ACwAAExample123",
        "public_identifier": "jane-example",
        "first_name": "Jane",
        "last_name": "Example",
        "full_name": "Jane Example",
        "headline": "CFO at Acme Analytics",
        "about": null,
        "location": {
          "text": "Ghent, Flemish Region, Belgium",
          "city": "Ghent",
          "state": "Flemish Region",
          "country": "Belgium",
          "country_code": "BE"
        },
        "picture_url": null,
        "connections_count": 500,
        "follower_count": 1204,
        "open_to_work": false,
        "hiring": false,
        "premium": true,
        "current_positions": [
          {
            "title": "Chief Financial Officer",
            "company_name": "Acme Analytics",
            "company_linkedin_url": "https://www.linkedin.com/company/acme-analytics",
            "location": "Ghent, Belgium",
            "employment_type": "Full-time",
            "workplace_type": "Hybrid",
            "start_date": {
              "year": 2026,
              "month": 7
            },
            "end_date": null,
            "is_current": true,
            "duration": "3 mos",
            "description": null
          }
        ],
        "experience": [
          {
            "title": "Chief Financial Officer",
            "company_name": "Acme Analytics",
            "company_linkedin_url": "https://www.linkedin.com/company/acme-analytics",
            "location": "Ghent, Belgium",
            "employment_type": "Full-time",
            "workplace_type": "Hybrid",
            "start_date": {
              "year": 2026,
              "month": 7
            },
            "end_date": null,
            "is_current": true,
            "duration": "3 mos",
            "description": null
          }
        ],
        "education": [
          {
            "school_name": "Ghent University",
            "school_linkedin_url": null,
            "degree": "Master of Science",
            "field_of_study": "Business Economics",
            "start_date": {
              "year": 2008,
              "month": null
            },
            "end_date": {
              "year": 2012,
              "month": null
            },
            "description": null
          }
        ],
        "skills": [
          "Financial Planning",
          "M&A"
        ],
        "languages": [
          {
            "name": "Dutch",
            "proficiency": "Native or bilingual proficiency"
          }
        ],
        "certifications": []
      },
      "company": {
        "name": "Acme Analytics",
        "linkedin_url": "https://www.linkedin.com/company/acme-analytics",
        "domain": "acme-analytics.example"
      },
      "credits_charged": 1,
      "save_input": {
        "name": "Jane Example",
        "linkedin_url": "https://www.linkedin.com/in/jane-example",
        "title": "Chief Financial Officer",
        "headline": "CFO at Acme Analytics",
        "company": "Acme Analytics",
        "company_linkedin_url": "https://www.linkedin.com/company/acme-analytics",
        "location": "Ghent, Flemish Region, Belgium",
        "country_code": "BE",
        "email": "jane@acme-analytics.example"
      }
    },
    {
      "input": "nobody@example.com",
      "status": "not_found",
      "person": null,
      "company": null,
      "credits_charged": 0
    }
  ],
  "credits_used": 1
}