Search
Run a natural language search against Orbit’s people index. Returns ranked profiles. Supports global and directory scopes. Costs 2 credits per successful request.
POST
The search endpoint accepts a plain English query and returns a ranked list of matching profiles. Orbit resolves your query through structured, semantic, and agentic search modes automatically — you don’t need to specify a mode. Each successful request costs credits; requests that return no results or fail validation are refunded.
Requests authenticate with a developer API key that has the
The plain-English
Validation, authentication, rate-limit, and credit failures before the stream starts return regular JSON errors. After the stream starts, errors are emitted on the event stream.
search:read scope. See Authentication.
Headers
Bearer sk_orb_... with the search:read scope.A UUID or client-generated key for safe retries.
Body parameters
Natural language description of the people you’re searching for. Cannot be empty.Example:
"founders in sf", "machine learning engineers at Series B startups"Number of results to return. Must be a positive integer. Maximum value is
100.Scope of the search. Omit this field or set
{"type":"global"} to search the full Orbit index. Use a directory-scoped value to restrict results to one or more directories.Optional structured search DSL. Use this when your integration already knows the exact filters or semantic clauses to run.
query is still required and should describe the same user intent in plain English. See Structured DSL for the full schema.Set to
true to generate match reasons for top results. Defaults to false.userIdis not accepted in the request body.searchId(search replay) is not accepted in the request body.- Personal API keys can only use global search. To use a directory scope, you must use an organization API key.
Search scope examples
- Global
- Single directory
- Multiple directories
Omit
searchScope entirely, or pass {"type":"global"}, to search the full Orbit index.Structured DSL example
UsestructuredIntent to provide explicit search clauses while still sending a human-readable query:
query is used for moderation, logging, summaries, match reasons, and search-quality training. It should align with structuredIntent; it does not need to restate every field.
entityClauses are not public yet. The server rejects entity clauses and server-owned resolved fields.
Streaming
UsePOST /v2/developer/search/sse when you want the initial results immediately and match-reason updates as they are generated. The SSE endpoint accepts the same request body as synchronous search, including structuredIntent, searchScope, and includeMatchReason.
Response
Always
"success" for a 200 response.Unique identifier for this search request. Useful for support and debugging.
Response headers
| Header | Description |
|---|---|
X-Developer-API-Credits-Remaining | Your remaining credit balance after this request was charged |
Credits
Each successful search costs 2 credits by default, regardless ofnumUsers or whether you use the synchronous or SSE endpoint. Credits are reserved before the search runs, so out-of-credit requests fail immediately without consuming search resources. If a search returns no results or fails, the reservation is refunded.
Rate limits
25 requests per second per API key, with bursts up to 100 requests. Rate limits are tracked per key, not per IP address. A429 response does not consume credits.
Error responses
400 — Bad request
400 — Bad request
| Code | Description |
|---|---|
developer_query_required | query is missing or empty |
developer_num_users_required | numUsers is missing or not a valid positive integer |
developer_num_users_limit_exceeded | numUsers exceeds the maximum of 100 |
developer_user_id_override_forbidden | Request body includes a userId field, which is not permitted |
developer_search_replay_unsupported | Request body includes a searchId field; search replay is not supported for developer API keys |
structured_intent_invalid | structuredIntent is malformed or contains unsupported values |
structured_intent_version_unsupported | structuredIntent.version is not "v1" |
structured_intent_entity_clauses_unsupported | entityClauses are not part of the public structured DSL |
structured_intent_server_owned_field | Request body includes a server-owned structured intent field |
401 — Unauthorized
401 — Unauthorized
402 — Payment required
402 — Payment required
| Code | Description |
|---|---|
developer_api_credits_insufficient | Your remaining credits are lower than the cost of this search |
403 — Forbidden
403 — Forbidden
| Code | Description |
|---|---|
invalid_api_key | The key is malformed, revoked, expired, or unknown |
missing_api_key_scope | The key does not have the search:read scope |
developer_api_key_organization_required | A directory scope was requested, but the key is a personal API key |
developer_api_key_organization_forbidden | The organization API key is not authorized for the requested organization search scope |
search_directory_access_api_key_forbidden | The organization API key does not have a matching directory search grant |
404 — Not found
404 — Not found
| Code | Description |
|---|---|
search_directory_not_found | One or more requested directories do not exist, are archived, or are unavailable for search. Also returned when a search runs successfully but no profiles matched — in this case, no credits are consumed. |
409 — Conflict
409 — Conflict
| Code | Description |
|---|---|
developer_api_idempotency_key_conflict | The idempotency key was reused with different request parameters. Use a different key. |
developer_api_idempotency_key_refunded | The idempotency key belongs to a previously refunded request. Send a fresh idempotency key to retry. |
429 — Rate limited
429 — Rate limited
| Code | Description |
|---|---|
developer_api_key_rate_limited | You have exceeded the Search rate limit for this API key |
