> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbitsearch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# How Orbit Search understands and routes your queries

> Learn how Orbit Search interprets natural language, which request fields are required, and how to scope a search to global profiles or private directories.

Orbit Search accepts plain English queries and handles the hard parts — query understanding, semantic matching, entity resolution, and ranking — automatically. You send a query like `"founders in San Francisco"` and receive ranked profile results. There is no query language to learn and no schema to map against; the API infers your intent from the natural language you provide.

If your integration already has structured filters, Search also accepts a [structured DSL](/api/search/structured-dsl) through `structuredIntent`. Use it when you want to bypass natural-language parsing for known clauses while keeping a plain-English `query` for moderation, logging, summaries, match reasons, and search-quality training. Developer Deep Search uses the same DSL as its request contract.

## The search endpoints

Use the synchronous endpoint for one JSON response, or the SSE endpoint when you want initial results followed by streamed updates:

```http theme={"dark"}
POST /v2/developer/search
POST /v2/developer/search/sse
```

Authenticate with your developer API key in the `Authorization` header:

```bash theme={"dark"}
curl -X POST "https://api.orbitsearch.com/v2/developer/search" \
  -H "Authorization: Bearer sk_orb_REDACTED" \
  -H "Idempotency-Key: your-unique-request-id" \
  -H "Content-Type: application/json" \
  -d '{"query":"founders in sf","numUsers":10}'
```

A successful response looks like this:

```json theme={"dark"}
{
  "status": "success",
  "searchId": "uuid",
  "payload": {
    "users": []
  }
}
```

<Note>
  Include an `Idempotency-Key` header on every search request. If your client retries the request after a network failure, the server uses this key to detect the duplicate and avoid charging credits twice. If you omit the header, the server falls back to the internal request ID — which protects within a single request but cannot deduplicate a later client retry. See [API credits](/concepts/credits) for full idempotency behavior.
</Note>

## Request fields

Search request bodies use these fields:

| Field              | Type    | Required | Description                                                         |
| ------------------ | ------- | -------- | ------------------------------------------------------------------- |
| `query`            | string  | Yes      | A natural language description of who you are looking for           |
| `numUsers`         | integer | Yes      | How many results to return; must be a positive integer, maximum 100 |
| `searchScope`      | object  | No       | Constrains where the search runs; defaults to `global` if omitted   |
| `structuredIntent` | object  | No       | Optional structured DSL plan for Search                             |

`userId` and `searchId` are not accepted in developer search requests. `POST /v2/developer/search` returns one synchronous response. `POST /v2/developer/search/sse` streams the same initial payload plus follow-up events such as match-reason updates. Developer Deep Search is the async surface: start a run with `POST /v2/developer/deep-search` and poll its status endpoint until the run completes.

## Search scopes

The `searchScope` field controls which corpus the search runs against. There are three scope shapes.

### Global search

Omitting `searchScope` or setting `type` to `"global"` runs the search across all public Orbit profiles. This is the default for personal API keys and works with any `search:read` key.

```json theme={"dark"}
{
  "query": "founders in sf",
  "numUsers": 10,
  "searchScope": { "type": "global" }
}
```

### Single directory search

The `directory` scope limits results to one specific directory by ID. Use this when you want to search a single private corpus you manage.

```json theme={"dark"}
{
  "query": "festival programmers",
  "numUsers": 10,
  "searchScope": { "type": "directory", "directoryId": "DIRECTORY_UUID" }
}
```

### Multi-directory search

The `directories` scope searches across multiple directories at once. All directories must belong to the same organization. Duplicate IDs are normalized automatically; archived or missing directories are rejected.

```json theme={"dark"}
{
  "query": "festival programmers",
  "numUsers": 10,
  "searchScope": {
    "type": "directories",
    "directoryIds": ["DIRECTORY_UUID_A", "DIRECTORY_UUID_B"]
  }
}
```

## Personal vs. organization API keys

Global search works with both personal and organization API keys. Directory-scoped search — the `directory` and `directories` scopes — requires an organization API key. Personal API keys are rejected for any scope that targets a private corpus.

For details on creating organization API keys and managing directory access, see [Organizations](/concepts/organizations) and [Search Directories](/concepts/directories).

## Reading profiles from search results

Search results include user IDs you can use to fetch full public profiles. Use the `GET /v2/developer/profiles/:id` endpoint with the same API key:

```bash theme={"dark"}
SEARCH_RESPONSE=$(
  curl -s -X POST "https://api.orbitsearch.com/v2/developer/search" \
    -H "Authorization: Bearer sk_orb_REDACTED" \
    -H "Content-Type: application/json" \
    -d '{"query":"founders in sf","numUsers":10}'
)

PROFILE_ID=$(echo "$SEARCH_RESPONSE" | jq -r '.payload.users[0].id')

curl "https://api.orbitsearch.com/v2/developer/profiles/$PROFILE_ID" \
  -H "Authorization: Bearer sk_orb_REDACTED"
```

Profile reads require the `profile:read` scope and cost 1 credit each. See [API credits](/concepts/credits) for details.
