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

# Read a search

> Read a search: its state, and its answer when it succeeded. Poll this route every
few seconds until `state` is `succeeded`, `failed` or `cancelled`.

The first read after the search ends charges it. That read carries the charge in
`X-Credits-Used` and in `credits_used`. Every later read returns
`X-Credits-Used: 0` and shows the same `credits_used`. A search that you streamed
to its end was charged by the stream, so its reads all return `X-Credits-Used: 0`.

The answer is in `output`, under one entity key: `person`, `company` or `job`.
The agent picks the columns. The body shows each column that your account may
receive, plus the contact columns, which every account receives.

<Note>
    Default `rate-limit` is 300 requests per minute, shared by the read, events, and cancel routes.
</Note>




## OpenAPI

````yaml /openapi-specs/2025-11-01/agent_search.yaml get /agent/searches/{search_id}
openapi: 3.0.3
info:
  title: Agent Search API
  version: '2025-11-01'
  description: >
    The Agent Search API (beta) takes a question in plain words and returns the
    matching

    people, companies or jobs, each with the reasons it matches. You send the
    question to `POST /agent/searches`. An agent searches the

    Crustdata datasets in the background, picks the columns of the answer, and
    checks each

    row against the requirements it read in your question.


    A search runs for tens of seconds to a few minutes. Read it with

    `GET /agent/searches/{search_id}` until `state` is `succeeded`, `failed` or
    `cancelled`,

    or stream its events with `Accept: text/event-stream`.


    All requests require a valid API key passed via the `Authorization` header
    as a Bearer

    token and an `x-api-version` header set to `2025-11-01`.
servers:
  - url: https://api.crustdata.com
    description: Production API server
security:
  - bearerAuth: []
tags:
  - name: Agent Search APIs
    description: Start, read, stream and cancel agent searches.
paths:
  /agent/searches/{search_id}:
    get:
      tags:
        - Agent Search APIs
      summary: Read an agent search
      description: >
        Read a search: its state, and its answer when it succeeded. Poll this
        route every

        few seconds until `state` is `succeeded`, `failed` or `cancelled`.


        The first read after the search ends charges it. That read carries the
        charge in

        `X-Credits-Used` and in `credits_used`. Every later read returns

        `X-Credits-Used: 0` and shows the same `credits_used`. A search that you
        streamed

        to its end was charged by the stream, so its reads all return
        `X-Credits-Used: 0`.


        The answer is in `output`, under one entity key: `person`, `company` or
        `job`.

        The agent picks the columns. The body shows each column that your
        account may

        receive, plus the contact columns, which every account receives.


        <Note>
            Default `rate-limit` is 300 requests per minute, shared by the read, events, and cancel routes.
        </Note>
      operationId: readAgentSearch
      parameters:
        - $ref: '#/components/parameters/ApiVersion'
        - $ref: '#/components/parameters/SearchId'
      responses:
        '200':
          headers:
            X-Credits-Used:
              $ref: '#/components/headers/XCreditsUsed'
          description: The search.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AgentSearch'
              examples:
                people_list:
                  summary: A person answer (3 rows)
                  value:
                    search_id: 1318-07fcae93f67c961a96c8758766b2fea1
                    query: The founders of Crustdata
                    state: succeeded
                    created_at: '2026-11-13T11:32:26.860998+00:00'
                    output:
                      note: null
                      reason: null
                      person:
                        constraints:
                          - id: c1
                            text: Founded Crustdata.
                            importance: hard
                        columns:
                          - key: name
                            label: Name
                            field: basic_profile.name
                          - key: profile_url
                            label: Profile URL
                            field: >-
                              social_handles.professional_network_identifier.profile_url
                          - key: basic_profile_headline
                            label: Headline
                            field: basic_profile.headline
                        rows:
                          - id: 1068035
                            values:
                              basic_profile_headline: >-
                                Co-founder at Crustdata (YC F24) | Infra for
                                building AI employees
                              name: Abhilash Chowdhary
                              profile_url: https://www.linkedin.com/in/abhilashchowdhary
                            constraints:
                              - constraint_id: c1
                                assessment: satisfied
                                evidence: >-
                                  Headline identifies him as Crustdata
                                  co-founder, and current employer title is
                                  Co-Founder & CEO.
                                fields:
                                  - basic_profile.headline
                          - id: 1148585
                            values:
                              basic_profile_headline: >-
                                Co-Founder at Crustdata (YC F24) | Building most
                                accurate search engine for people search
                              name: Manmohit Grewal
                              profile_url: https://www.linkedin.com/in/manmohitgrewal
                            constraints:
                              - constraint_id: c1
                                assessment: satisfied
                                evidence: >-
                                  Headline and current role identify him as a
                                  Crustdata co-founder.
                                fields:
                                  - basic_profile.headline
                          - id: 402126
                            values:
                              basic_profile_headline: >-
                                Co-founder at Crustdata (YC F24) | Real-time B2B
                                data for AI Agents
                              name: Chris Pisarski
                              profile_url: https://www.linkedin.com/in/chris-pisarski
                            constraints:
                              - constraint_id: c1
                                assessment: satisfied
                                evidence: >-
                                  Headline identifies him as co-founder, and his
                                  summary says he is building Crustdata.
                                fields:
                                  - basic_profile.headline
                                  - professional_network.summary
                    credits_used:
                      agent_cost: 0.66
                      search_cost: 0.1385
                      enrich_cost: 0
                      contact_cost: 0
                      total_cost: 0.7985
                    error: null
                company_list:
                  summary: A company answer (2 of 25 rows)
                  value:
                    search_id: 1318-c379345672f34397a53fafff6dcfaa83
                    query: Fintech companies in Berlin with 50 to 200 employees
                    state: succeeded
                    created_at: '2026-11-13T11:32:55.584699+00:00'
                    output:
                      note: null
                      reason: null
                      company:
                        constraints:
                          - id: c1
                            text: The company is a fintech company.
                            importance: core
                          - id: c2
                            text: The company is headquartered in Berlin.
                            importance: hard
                          - id: c3
                            text: The company has between 50 and 200 employees.
                            importance: hard
                        columns:
                          - key: name
                            label: Name
                            field: basic_info.name
                          - key: profile_url
                            label: Profile URL
                            field: basic_info.professional_network_url
                          - key: domain
                            label: Domain
                            field: basic_info.primary_domain
                          - key: locations_headquarters
                            label: Headquarters
                            field: locations.headquarters
                          - key: headcount_total
                            label: Headcount
                            field: headcount.total
                        rows:
                          - id: 6034604
                            values:
                              name: Qwist
                              domain: qwist.com
                              profile_url: https://www.linkedin.com/company/qwist
                              headcount_total: 96
                              locations_headquarters: Berlin, Berlin, Germany
                            constraints:
                              - constraint_id: c1
                                assessment: satisfied
                                evidence: >-
                                  Categories include FinTech and description
                                  details financial-data and financing services.
                                fields:
                                  - taxonomy.categories
                                  - basic_info.description
                              - constraint_id: c2
                                assessment: satisfied
                                evidence: >-
                                  Headquarters location is listed as Berlin,
                                  Germany.
                                fields:
                                  - locations.headquarters
                              - constraint_id: c3
                                assessment: satisfied
                                evidence: >-
                                  Description states the company has around 120
                                  employees.
                                fields:
                                  - basic_info.description
                          - id: 1123623
                            values:
                              name: BANCOS
                              domain: bancos.com
                              profile_url: https://www.linkedin.com/company/bancos-ag
                              headcount_total: 55
                              locations_headquarters: Berlin, Berlin, Germany
                            constraints:
                              - constraint_id: c1
                                assessment: satisfied
                                evidence: >-
                                  Company develops core banking software for
                                  banks and fintechs and has finance/banking
                                  categories.
                                fields:
                                  - basic_info.description
                                  - taxonomy.categories
                              - constraint_id: c2
                                assessment: satisfied
                                evidence: >-
                                  Headquarters location is explicitly Berlin,
                                  Germany.
                                fields:
                                  - locations.headquarters
                              - constraint_id: c3
                                assessment: satisfied
                                evidence: >-
                                  Description says around 70 people and latest
                                  count is 55, both within range.
                                fields:
                                  - basic_info.description
                                  - headcount.total
                    credits_used:
                      agent_cost: 0.96
                      search_cost: 0.2255
                      enrich_cost: 0
                      contact_cost: 0
                      total_cost: 1.1855
                    error: null
                found_nothing:
                  summary: A search that found nothing costs 0
                  value:
                    search_id: 1318-38e3caabee114840a52225672135d096
                    query: People who work at Crustdata and live in Antarctica
                    state: succeeded
                    created_at: '2026-11-13T12:16:43.926200+00:00'
                    output:
                      note: >-
                        We found no people currently working at Crustdata whose
                        recorded location is Antarctica.
                      reason: no_match
                      person:
                        constraints:
                          - id: c1
                            text: is currently employed at Crustdata
                            importance: hard
                          - id: c2
                            text: is based in Antarctica
                            importance: hard
                        columns:
                          - key: name
                            label: Name
                            field: basic_profile.name
                          - key: profile_url
                            label: Profile URL
                            field: >-
                              social_handles.professional_network_identifier.profile_url
                        rows: []
                    credits_used:
                      agent_cost: 0
                      search_cost: 0
                      enrich_cost: 0
                      contact_cost: 0
                      total_cost: 0
                    error: null
                running:
                  summary: A search that has not ended
                  value:
                    search_id: 1318-36914219bab84371bd119fa6c2458b84
                    query: Software engineers in Bangalore who write Rust
                    state: running
                    created_at: '2026-11-13T11:55:59.475295+00:00'
                    output: null
                    credits_used:
                      agent_cost: 0
                      search_cost: 0
                      enrich_cost: 0
                      contact_cost: 0
                      total_cost: 0
                    error: null
                cancelled:
                  summary: A cancelled search costs 0
                  value:
                    search_id: 1318-ce76b669c98d42849a0c1d4239040e03
                    query: Software engineers in Bangalore who write Rust
                    state: cancelled
                    created_at: '2026-11-13T11:33:53.652735+00:00'
                    output: null
                    credits_used:
                      agent_cost: 0
                      search_cost: 0
                      enrich_cost: 0
                      contact_cost: 0
                      total_cost: 0
                    error: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/UnknownSearch'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ReadUnavailable'
components:
  parameters:
    ApiVersion:
      name: x-api-version
      in: header
      required: true
      schema:
        type: string
        enum:
          - '2025-11-01'
        default: '2025-11-01'
        example: '2025-11-01'
      description: API version to use. This endpoint currently requires `2025-11-01`.
    SearchId:
      name: search_id
      in: path
      required: true
      description: The `search_id` that the start returned.
      schema:
        type: string
        example: 1318-07fcae93f67c961a96c8758766b2fea1
  headers:
    XCreditsUsed:
      description: >-
        Exact credits this request deducted, as a decimal string (for example
        `0.9125`). On these routes, only the first read after a search ends
        carries a value above `0`. Responses generated before a request reaches
        the API, such as rate-limit `429`s, do not carry it.
      schema:
        type: string
        example: '0.9125'
    RetryAfter:
      description: Seconds to wait before you try again.
      schema:
        type: string
        example: '5'
  schemas:
    AgentSearch:
      type: object
      description: >-
        A search, with its answer when it succeeded. Ignore a key you do not
        know, because new keys can come.
      required:
        - search_id
        - query
        - state
        - created_at
        - output
        - credits_used
        - error
      properties:
        search_id:
          type: string
          description: The id that the start returned.
          example: 1318-07fcae93f67c961a96c8758766b2fea1
        query:
          type: string
          description: The question as you sent it.
          example: The founders of Crustdata
        state:
          $ref: '#/components/schemas/AgentSearchState'
        created_at:
          type: string
          format: date-time
          description: When the search started.
          example: '2026-11-13T11:32:26.860998+00:00'
        output:
          allOf:
            - $ref: '#/components/schemas/AgentOutput'
          nullable: true
          description: The answer. It is set only when `state` is `succeeded`.
          example:
            note: null
            reason: null
            company:
              constraints:
                - id: c2
                  text: The company is headquartered in Berlin.
                  importance: hard
              columns:
                - key: name
                  label: Name
                  field: basic_info.name
              rows:
                - id: 675954
                  values:
                    name: Billie
                  constraints:
                    - constraint_id: c2
                      assessment: satisfied
                      evidence: Headquarters are listed in Berlin, Germany.
                      fields:
                        - locations.headquarters
        credits_used:
          $ref: '#/components/schemas/AgentCreditsUsed'
        error:
          allOf:
            - $ref: '#/components/schemas/AgentSearchFailure'
          nullable: true
          description: Why the search failed. It is set only when `state` is `failed`.
          example:
            type: internal_error
            message: The search did not finish in time. A narrower query may finish.
            metadata:
              - retryable: true
    AgentSearchState:
      type: string
      description: >-
        The state of a search. `succeeded`, `failed` and `cancelled` are end
        states. Every search in progress is `running` today. `queued` is not
        returned today; a later release adds it for a search that waits in a
        queue. Treat every state that is not an end state as in progress. This
        enum is closed.
      enum:
        - queued
        - running
        - succeeded
        - failed
        - cancelled
      example: running
    AgentOutput:
      type: object
      description: >-
        The answer. Today it has exactly one entity key, `person`, `company` or
        `job`, and the agent picks it. Find the entity by its key.
      properties:
        note:
          type: string
          nullable: true
          maxLength: 512
          description: >-
            Plain text about the whole answer, for a person to read. It is set
            when `reason` is set, except when every row of the answer was left
            out.
        reason:
          type: string
          nullable: true
          description: >-
            Why the answer is short or empty. Null on a full answer. This enum
            is open: handle a value you do not know. Values today: `partial`,
            `unsupported_data`, `no_match`, `unsupported_entity`,
            `not_a_search`, `malformed`, `restricted`.
          example: partial
        person:
          $ref: '#/components/schemas/AgentEntity'
        company:
          $ref: '#/components/schemas/AgentEntity'
        job:
          $ref: '#/components/schemas/AgentEntity'
    AgentCreditsUsed:
      type: object
      description: >-
        The charge, in credits. It grows with the effort of the search. Every
        key is 0 until the search is charged. A search that finds nothing,
        fails, or is cancelled costs 0. `total_cost` is the sum of the 4 parts.
      required:
        - agent_cost
        - search_cost
        - enrich_cost
        - contact_cost
        - total_cost
      properties:
        agent_cost:
          type: number
          description: >-
            The agent's work on the search. It grows with the effort of the
            search.
          example: 0.78
        search_cost:
          type: number
          description: >-
            The data that the agent searched. It grows with the effort of the
            search.
          example: 0.1325
        enrich_cost:
          type: number
          description: >-
            The records that the agent fetched in full. It grows with the effort
            of the search.
          example: 0
        contact_cost:
          type: number
          description: >-
            The contact data that the agent looked up. Each type is charged once
            for each person who has a value of that type, and a person with no
            value of a type costs 0 for it. It also counts people whose contact
            data the agent looked up and who are not in the final `rows`.
          example: 0
        total_cost:
          type: number
          description: The charge.
          example: 0.9125
    AgentSearchFailure:
      type: object
      description: Why a search failed, and whether starting it again may work.
      properties:
        type:
          type: string
          example: internal_error
        message:
          type: string
          example: The search did not finish in time. A narrower query may finish.
        metadata:
          type: array
          items:
            type: object
            properties:
              retryable:
                type: boolean
    ErrorResponse:
      type: object
      description: >-
        The body of almost every error response. A `405` and a `404` on an
        unknown path have another body.
      required:
        - error
      properties:
        error:
          type: object
          required:
            - type
            - message
            - metadata
          properties:
            type:
              type: string
              example: invalid_request
            message:
              type: string
            metadata:
              type: array
              description: >-
                Empty, or `[{"retryable": true, "retry_after_seconds": N}]` on a
                error that can clear if you try again later.
              items:
                type: object
                properties:
                  retryable:
                    type: boolean
                  retry_after_seconds:
                    type: integer
    AgentEntity:
      type: object
      description: The answer about one entity type.
      required:
        - constraints
        - columns
        - rows
      properties:
        constraints:
          type: array
          maxItems: 8
          description: The requirements that the agent read in the query for this entity.
          items:
            $ref: '#/components/schemas/AgentConstraint'
          example:
            - id: c1
              text: Founded Crustdata.
              importance: hard
        columns:
          type: array
          maxItems: 9
          description: >-
            The identity columns first (at most 3), then the columns that the
            agent chose (at most 6), in the agent's order. A field column shows
            only when your account may receive its field. Contact columns show
            for every account.
          items:
            $ref: '#/components/schemas/AgentColumn'
        rows:
          type: array
          maxItems: 200
          description: One row per record, best first. Empty when the agent found nothing.
          items:
            $ref: '#/components/schemas/AgentRow'
    AgentConstraint:
      type: object
      description: One requirement that the agent read in the query.
      required:
        - id
        - text
        - importance
      properties:
        id:
          type: string
          description: The id that row verdicts name in `constraint_id`.
          example: c1
        text:
          type: string
          maxLength: 128
          description: The requirement in plain words.
          example: The company is headquartered in Berlin.
        importance:
          type: string
          description: How much the requirement counts. This enum is closed.
          enum:
            - hard
            - core
            - soft
    AgentColumn:
      type: object
      description: >-
        One column of the answer. A field column names a field path; an agent
        column has `field` null.
      required:
        - key
        - label
        - field
      properties:
        key:
          type: string
          pattern: ^[a-z0-9_]{1,32}$
          description: >-
            The key of this column's cells in `rows[].values`. Unique in the
            answer.
          example: headcount
        label:
          type: string
          maxLength: 64
          description: A name for the column, for a person to read.
          example: Employees
        field:
          type: string
          nullable: true
          description: >-
            The field path of the record that fills this column, for example
            `headcount.total`. Null on an agent column, whose cells the agent
            wrote. `contact.business_emails`, `contact.personal_emails` and
            `contact.phone_numbers` mark a contact column.
          example: headcount.total
    AgentRow:
      type: object
      description: One record of the answer, with its cells and its verdicts.
      required:
        - id
        - values
        - constraints
      properties:
        id:
          type: integer
          description: >-
            The Crustdata id of the record: `crustdata_person_id`,
            `crustdata_company_id` or `crustdata_job_id`, as the entity key
            says.
          example: 675954
        values:
          type: object
          description: >-
            The cells of the shown columns, by column key. A missing key means
            null. `null`, `""` and `[]` all mean empty.
          additionalProperties:
            $ref: '#/components/schemas/AgentCell'
        constraints:
          type: array
          description: >-
            At most one verdict for each constraint. A constraint that was not
            checked in time has no verdict, so match verdicts by
            `constraint_id`, not by position.
          items:
            $ref: '#/components/schemas/AgentVerdict'
    AgentCell:
      description: >-
        A string, a number, a boolean, a list of those, or null. A field under a
        list, such as `experience.employment_details.current.title`, gives a
        list. A contact cell is a list of strings. A number larger than 2^53 - 1
        comes as a string.
      nullable: true
      oneOf:
        - type: string
        - type: number
        - type: boolean
        - type: array
          items:
            oneOf:
              - type: string
              - type: number
              - type: boolean
    AgentVerdict:
      type: object
      description: The agent's verdict on one constraint for one row.
      required:
        - constraint_id
        - assessment
        - evidence
        - fields
      properties:
        constraint_id:
          type: string
          example: c2
        assessment:
          type: string
          description: The verdict. This enum is closed.
          enum:
            - satisfied
            - unknown
            - violated
        evidence:
          type: string
          maxLength: 256
          description: >-
            Why, in plain words. It is `""` when the evidence quotes a field
            that your account may not receive.
          example: Headquarters are listed in Berlin, Germany.
        fields:
          type: array
          maxItems: 4
          description: The field paths that the evidence reads.
          items:
            type: string
          example:
            - locations.headquarters
  responses:
    Unauthorized:
      description: The API key is missing or not valid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalid_api_key:
              summary: No API key, or an API key that is not valid
              value:
                error:
                  type: unauthorized
                  message: Invalid API key in request.
                  metadata: []
    UnknownSearch:
      description: No search of your account has this `search_id`.
      headers:
        X-Credits-Used:
          $ref: '#/components/headers/XCreditsUsed'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            unknown_search:
              summary: The search_id is not one of yours
              value:
                error:
                  type: not_found
                  message: Unknown search_id.
                  metadata: []
    RateLimited:
      description: >-
        More than 300 requests in one minute on the read, events, and cancel
        routes. This `429` has no `Retry-After` header: wait for the seconds in
        `X-RateLimit-Reset`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            rate_limit:
              summary: The rate limit is used up
              value:
                error:
                  type: rate_limit_error
                  message: >-
                    Rate limit exceeded for this endpoint. Please write to
                    gtm@crustdata.co.
                  metadata: []
    ReadUnavailable:
      description: >-
        Agent Search did not answer, or the rows of an ended search are not
        ready yet. Try again after `Retry-After` seconds. These messages come
        from the api code and were not reproduced live.
      headers:
        X-Credits-Used:
          $ref: '#/components/headers/XCreditsUsed'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            not_answered:
              summary: Agent Search did not answer
              value:
                error:
                  type: service_unavailable
                  message: Agent Search did not answer. Try again in a few seconds.
                  metadata:
                    - retryable: true
                      retry_after_seconds: 5
            rows_not_ready:
              summary: The rows of an ended search are not ready
              value:
                error:
                  type: service_unavailable
                  message: >-
                    The rows of this search are not ready. Try again in a few
                    seconds.
                  metadata:
                    - retryable: true
                      retry_after_seconds: 5
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: API key passed as a Bearer token in the `Authorization` header.

````

## Related topics

- [API Introduction](https://docs.crustdata.com/openapi-specs/2025-11-01/introduction.md)
- [Read events](https://docs.crustdata.com/api-reference/agent-search-apis/read-the-events-of-an-agent-search.md)
- [Agent Search API](https://docs.crustdata.com/agent-search-docs/overview.md)
- [Cancel a search](https://docs.crustdata.com/api-reference/agent-search-apis/cancel-an-agent-search.md)
- [People Search API](https://docs.crustdata.com/person-docs/search/introduction.md)
