{
  "openapi": "3.1.0",
  "info": {
    "title": "Datalayer API",
    "version": "0.2.0",
    "description": "Four account-scoped company and people operations. Private preview: account access is restricted and paid checkout is not enabled. An active profile allowance is required. Searches are included; successful new lookups use one profile unless covered by an eligible 24-hour repeat or idempotent replay. REST and MCP share the same allowance. Work-email checks are opt-in; delivery and ownership are not guaranteed."
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Datalayer API key",
        "description": "Send Authorization: Bearer dl_live_<64 lowercase hexadecimal characters>. Approved users can create account-scoped, revocable keys in the Datalayer dashboard. A key does not grant a profile allowance. Dashboard session cookies are not API credentials."
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": false,
        "description": "Recommended for lookup retries. A key is scoped to this account and bound to the normalized operation/input. Reuse it only for the same request within 24 hours; changed input, an expired key, or a different resolved profile returns 409. A replay refetches data but deducts no additional profile. If omitted, the server creates a request ID. A network failure after database commit starts can leave a completed deduction; a timeout alone does not imply zero usage.",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 128,
          "pattern": "^[A-Za-z0-9_-]{1,128}$"
        }
      }
    },
    "schemas": {
      "UsageMetadata": {
        "type": "object",
        "required": [
          "request_id",
          "retrieved_at",
          "upstream_requests",
          "billing_status",
          "profiles_used"
        ],
        "properties": {
          "request_id": {
            "type": "string",
            "description": "Account-scoped request/idempotency identifier."
          },
          "retrieved_at": {
            "type": "string",
            "format": "date-time",
            "description": "UTC time of this retrieval, including a replay that refetches provider data."
          },
          "upstream_requests": {
            "type": "integer",
            "minimum": 0,
            "description": "Number of MixRank requests made for this operation, including requested email checks."
          },
          "billing_status": {
            "type": "string",
            "enum": [
              "search_included",
              "profile_deducted",
              "repeat_included",
              "idempotent_replay"
            ],
            "description": "Whether this response created a new profile deduction or was included."
          },
          "profiles_used": {
            "type": "integer",
            "enum": [
              0,
              1
            ],
            "description": "Actual profile deduction caused by this request. Included searches, qualifying repeats and idempotent replays are 0."
          }
        },
        "additionalProperties": false
      },
      "WorkEmail": {
        "type": "object",
        "required": [
          "status",
          "emails"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "not_requested",
              "available",
              "no_current_employer_match"
            ]
          },
          "emails": {
            "type": "array",
            "maxItems": 5,
            "items": {
              "type": "object",
              "required": [
                "email",
                "classification",
                "employer_domain_match",
                "verification_status",
                "checked_at",
                "is_catch_all"
              ],
              "properties": {
                "email": {
                  "type": "string",
                  "format": "email"
                },
                "classification": {
                  "type": "string",
                  "const": "provider_tagged_business"
                },
                "employer_domain_match": {
                  "type": "boolean",
                  "const": true
                },
                "verification_status": {
                  "type": "string",
                  "enum": [
                    "valid",
                    "invalid",
                    "uncertain",
                    "not_checked"
                  ],
                  "description": "Bounded provider validation. Catch-all is uncertain; failed, stale or unsupported checks are not_checked."
                },
                "checked_at": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                },
                "is_catch_all": {
                  "type": [
                    "boolean",
                    "null"
                  ]
                }
              },
              "additionalProperties": false
            }
          },
          "note": {
            "type": "string"
          }
        },
        "additionalProperties": false,
        "description": "Only explicitly requested provider-tagged business addresses matching the observed employer website domain are included. Verification does not prove ownership or guarantee delivery."
      },
      "DataResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "description": "Normalized search results or profile. Search results are previews. Full profile fields may be null when unavailable.",
            "properties": {
              "work_email": {
                "$ref": "#/components/schemas/WorkEmail"
              }
            },
            "additionalProperties": true
          },
          "meta": {
            "$ref": "#/components/schemas/UsageMetadata"
          }
        },
        "additionalProperties": false
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      }
    }
  },
  "paths": {
    "/v1/companies/search": {
      "post": {
        "operationId": "search_companies",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "limit": {
                    "default": 10,
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 25
                  },
                  "offset": {
                    "default": 0,
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1000
                  }
                },
                "required": [
                  "query"
                ],
                "additionalProperties": false
              },
              "example": {
                "query": "Example",
                "limit": 10,
                "offset": 0
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Normalized data with current shared account usage metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataResponse"
                },
                "examples": {
                  "synthetic": {
                    "summary": "Synthetic example; not a real profile or live request",
                    "value": {
                      "data": {
                        "results": [
                          {
                            "company_id": "123",
                            "name": "Example Company",
                            "website": "https://example.com/",
                            "industries": [],
                            "headquarters": {
                              "city": null,
                              "region": null,
                              "country": null
                            },
                            "employee_size": null,
                            "description": null,
                            "source_updated_at": null
                          }
                        ],
                        "offset": 0,
                        "limit": 10,
                        "total": 1
                      },
                      "meta": {
                        "request_id": "example-request-001",
                        "retrieved_at": "2026-09-21T12:00:00Z",
                        "upstream_requests": 1,
                        "billing_status": "search_included",
                        "profiles_used": 0
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, input, or Idempotency-Key. No profile deducted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked account API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "No active profile grant, or no allowance available at settlement. No profile returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Data operations require POST.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict; company domain lookup may also require disambiguation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 16 KiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Account data-operation limit (60 requests per fixed minute) or provider rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Provider failure, timeout, invalid/unidentifiable profile, or unsupported response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporary application/database failure or a cancelled/over-budget request. The API checks a 40-second elapsed budget before settlement, but transport failure after commit starts can leave a completed deduction. Retry with the same Idempotency-Key; a timeout alone does not prove zero usage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Search companies",
        "description": "Find brief company previews by keyword with bounded pagination. An empty search succeeds with an empty results array. Included with an active profile grant; no profile deduction."
      }
    },
    "/v1/companies/lookup": {
      "post": {
        "operationId": "get_company",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "type": "object",
                "properties": {
                  "company_id": {
                    "type": "string",
                    "pattern": "^[1-9][0-9]{0,19}$"
                  },
                  "domain": {
                    "type": "string",
                    "pattern": "^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z]{2,63}$",
                    "description": "Website domain, without scheme/path. Input is trimmed and normalized to lowercase."
                  }
                },
                "additionalProperties": false,
                "oneOf": [
                  {
                    "required": [
                      "company_id"
                    ],
                    "not": {
                      "required": [
                        "domain"
                      ]
                    }
                  },
                  {
                    "required": [
                      "domain"
                    ],
                    "not": {
                      "required": [
                        "company_id"
                      ]
                    }
                  }
                ]
              },
              "example": {
                "company_id": "123"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Normalized data with current shared account usage metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataResponse"
                },
                "examples": {
                  "synthetic": {
                    "summary": "Synthetic example; not a real profile or live request",
                    "value": {
                      "data": {
                        "company_id": "123",
                        "name": "Example Company",
                        "website": "https://example.com/",
                        "profile_url": null,
                        "description": null,
                        "logo_url": null,
                        "founded_year": null,
                        "company_type": null,
                        "employee_count": null,
                        "employee_size": null,
                        "headquarters": {
                          "city": null,
                          "region": null,
                          "country": null
                        },
                        "locations": [],
                        "industries": [],
                        "specialties": [],
                        "industry_codes": {
                          "sic": [],
                          "naics": []
                        },
                        "source_updated_at": null,
                        "coverage_note": "Employee counts and size bands are separate provider observations and may disagree. Current staffing is not independently verified."
                      },
                      "meta": {
                        "request_id": "example-request-001",
                        "retrieved_at": "2026-09-21T12:00:00Z",
                        "upstream_requests": 1,
                        "billing_status": "profile_deducted",
                        "profiles_used": 1
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, input, or Idempotency-Key. No profile deducted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked account API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "No active profile grant, or no allowance available at settlement. No profile returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No matching company or person identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Data operations require POST.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict; company domain lookup may also require disambiguation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 16 KiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Account data-operation limit (60 requests per fixed minute) or provider rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Provider failure, timeout, invalid/unidentifiable profile, or unsupported response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporary application/database failure or a cancelled/over-budget request. The API checks a 40-second elapsed budget before settlement, but transport failure after commit starts can leave a completed deduction. Retry with the same Idempotency-Key; a timeout alone does not prove zero usage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Get company",
        "description": "Retrieve one full company profile by exactly one returned company ID or website domain. A new successful profile uses one allowance unit; canonical repeats within 24 hours of the paid retrieval are included for the same account.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      }
    },
    "/v1/people/search": {
      "post": {
        "operationId": "search_people",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "company": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "country": {
                    "type": "string",
                    "pattern": "^[A-Z]{2}$"
                  },
                  "skill": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "limit": {
                    "default": 10,
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 25
                  },
                  "offset": {
                    "default": 0,
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1000
                  }
                },
                "additionalProperties": false,
                "anyOf": [
                  {
                    "required": [
                      "query"
                    ]
                  },
                  {
                    "required": [
                      "company"
                    ]
                  }
                ]
              },
              "example": {
                "query": "Example",
                "limit": 10,
                "offset": 0
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Normalized data with current shared account usage metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataResponse"
                },
                "examples": {
                  "synthetic": {
                    "summary": "Synthetic example; not a real profile or live request",
                    "value": {
                      "data": {
                        "results": [
                          {
                            "person_id": "456",
                            "name": "Example Person",
                            "title": null,
                            "company_name": null,
                            "location": null,
                            "country": null,
                            "profile_url": "https://www.linkedin.com/in/example-person/",
                            "source_updated_at": null
                          }
                        ],
                        "offset": 0,
                        "limit": 10,
                        "total": {
                          "value": null,
                          "relation": "gte"
                        }
                      },
                      "meta": {
                        "request_id": "example-request-001",
                        "retrieved_at": "2026-09-21T12:00:00Z",
                        "upstream_requests": 1,
                        "billing_status": "search_included",
                        "profiles_used": 0
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, input, or Idempotency-Key. No profile deducted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked account API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "No active profile grant, or no allowance available at settlement. No profile returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Data operations require POST.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict; company domain lookup may also require disambiguation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 16 KiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Account data-operation limit (60 requests per fixed minute) or provider rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Provider failure, timeout, invalid/unidentifiable profile, or unsupported response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporary application/database failure or a cancelled/over-budget request. The API checks a 40-second elapsed budget before settlement, but transport failure after commit starts can leave a completed deduction. Retry with the same Idempotency-Key; a timeout alone does not prove zero usage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Search people",
        "description": "Find professional profile previews by query or exact company name; optionally filter by title, country, or skill. At least one of query/company is required. Included with an active grant; no profile deduction. Staging has returned successful results in about 20–23 seconds. The provider HTTP request is bounded at 30 seconds, with an 8-second Elasticsearch query timeout; timed-out or failed-shard partial responses are rejected."
      }
    },
    "/v1/people/lookup": {
      "post": {
        "operationId": "get_person",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$schema": "https://json-schema.org/draft/2020-12/schema",
                "type": "object",
                "properties": {
                  "person_id": {
                    "type": "string",
                    "pattern": "^[1-9][0-9]{0,19}$"
                  },
                  "profile_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Public LinkedIn profile URL under /in/, without credentials, a query, fragment, or non-default port."
                  },
                  "include": {
                    "default": [],
                    "maxItems": 1,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "const": "work_email"
                    },
                    "description": "Optional work_email requests return per-address verification status; no separate email price."
                  }
                },
                "additionalProperties": false,
                "oneOf": [
                  {
                    "required": [
                      "person_id"
                    ],
                    "not": {
                      "required": [
                        "profile_url"
                      ]
                    }
                  },
                  {
                    "required": [
                      "profile_url"
                    ],
                    "not": {
                      "required": [
                        "person_id"
                      ]
                    }
                  }
                ]
              },
              "example": {
                "person_id": "456"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Normalized data with current shared account usage metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataResponse"
                },
                "examples": {
                  "synthetic": {
                    "summary": "Synthetic example; not a real profile or live request",
                    "value": {
                      "data": {
                        "person_id": "456",
                        "name": "Example Person",
                        "profile_url": "https://www.linkedin.com/in/example-person/",
                        "headline": null,
                        "title": null,
                        "summary": null,
                        "location": {
                          "text": null,
                          "country": null
                        },
                        "company": null,
                        "skills": [],
                        "languages": [],
                        "experience": [],
                        "education": [],
                        "source_updated_at": null,
                        "work_email": {
                          "status": "not_requested",
                          "emails": []
                        }
                      },
                      "meta": {
                        "request_id": "example-request-001",
                        "retrieved_at": "2026-09-21T12:00:00Z",
                        "upstream_requests": 1,
                        "billing_status": "profile_deducted",
                        "profiles_used": 1
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, input, or Idempotency-Key. No profile deducted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked account API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "402": {
            "description": "No active profile grant, or no allowance available at settlement. No profile returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "No matching company or person identity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Data operations require POST.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict; company domain lookup may also require disambiguation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Request body exceeds 16 KiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Account data-operation limit (60 requests per fixed minute) or provider rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "502": {
            "description": "Provider failure, timeout, invalid/unidentifiable profile, or unsupported response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "Temporary application/database failure or a cancelled/over-budget request. The API checks a 40-second elapsed budget before settlement, but transport failure after commit starts can leave a completed deduction. Retry with the same Idempotency-Key; a timeout alone does not prove zero usage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        },
        "summary": "Get person",
        "description": "Retrieve one person by exactly one returned person ID or public LinkedIn /in/ URL. Include work_email only when contact information is requested. Available employer-domain business addresses receive bounded verification. A valid person profile counts even if an email is absent, invalid or uncertain.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ]
      }
    }
  },
  "servers": [
    {
      "url": "https://api.datalayer.so",
      "description": "Production API (private preview)"
    }
  ]
}
