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

# Search a data source

> Search any supported data source by keyword and return the single most
relevant result. This is the primary endpoint of the API.

Supported `source` values (aliases in parentheses): `wiki` (`wikipedia`),
`census`, `arxiv`, `gutenberg`, `fooddata`, `paperswithcode`, `edgar`
(`sec`, `sec-edgar`), `news` (`frontpage-news`), `stackexchange`
(`stackoverflow`, `stack-exchange`), `pypi`, `openalex`.

`keywords` is free text and may contain spaces and slashes; URL-encode it.

```bash
curl -H "Authorization: Bearer $DATAVILLE_API_KEY" \
  "https://api.dataville.com/arxiv/attention%20is%20all%20you%20need"
```




## OpenAPI

````yaml /openapi/openapi.yaml get /{source}/{keywords}
openapi: 3.0.3
info:
  title: Dataville API
  version: 1.0.0
  description: >
    Dataville is a unified data API: a single REST surface over Wikipedia,
    arXiv,

    Project Gutenberg, the US Census, USDA FoodData, Papers with Code, SEC
    EDGAR,

    OpenAlex, PyPI and Stack Exchange — plus bulk CSV/Parquet/DuckDB export, a

    SQL endpoint, and "bring your own data" Google Sheets connections.


    ## Authentication


    Data, export and query endpoints never hard-reject at the middleware level —
    an

    unauthenticated caller simply gets the anonymous tier (50 requests per day
    per

    IP).


    ### API key


    ```

    Authorization: Bearer dataville_xxxxxxxxxxxxxxxx

    ```


    Create and manage keys from the **API Keys** page in the

    [Dataville dashboard](https://app.dataville.com). Keys start with
    `dataville_`

    (legacy keys start with `datax_`). For clients that cannot set headers —
    DuckDB

    WASM, the DuckDB CLI's `httpfs` reader — the same key may be passed as the

    `?token=` query parameter.


    The Dataville web app authenticates with its own session tokens; those
    routes

    are internal and not part of the public API surface.


    ## Credits and metering


    Authenticated usage is metered against a monthly **Dataville credit**
    balance in

    USD, shared across an account's sessions and API keys. Each tier is granted

    credit every month — Free **$5**, Developer **$29**, Pro **$99** — and each

    query deducts a per-source, per-tier amount:


    | Class | Free | Developer | Pro |

    | --- | --- | --- | --- |

    | Open/public datasets | $0.0050 | $0.0050 | $0.0040 |

    | Wikipedia (premium) | $0.0250 | $0.0150 | $0.0125 |


    A `POST /api/v1/query` call is charged per row returned. When the balance

    reaches zero the API returns **402 Payment Required** until the monthly
    reset,

    a plan upgrade, or a credit top-off. Every metered response carries:


    - `X-Credits-Remaining` — remaining balance, USD

    - `X-Credit-Cost` — amount charged for this request, USD


    Check your request quota any time via `GET /api/v1/auth/usage`; your credit

    balance is reported on every metered response in `X-Credits-Remaining` and
    on

    the dashboard's **Billing** page.


    ## Rate limiting


    Anonymous callers are limited by IP (50 requests per 24 hours) and receive

    **429** when they exceed it, with `X-RateLimit-Limit`,
    `X-RateLimit-Remaining`

    and `X-RateLimit-Reset` headers. Authenticated callers are governed by
    credits

    rather than a request count. Export and SQL routes carry their own stricter

    limit (1,000 per day per account), as does support submission (5 per hour).


    ## Errors


    Every error body carries a human-readable `error`/`message` string that is
    safe

    to show a user verbatim, and data-source errors additionally carry a stable

    `data.code` (`UPSTREAM_RATE_LIMITED`, `UPSTREAM_UNAVAILABLE`,

    `UPSTREAM_FORBIDDEN`, `UPSTREAM_BAD_RESPONSE`, `SOURCE_UNAVAILABLE`,

    `INTERNAL_ERROR`) that clients should branch on instead of parsing prose.
    When

    an upstream tells us how long to wait, the response sets `Retry-After`.


    ## Stale results


    A live source that is down is answered from Dataville's own stored copy
    where

    one exists. Those responses include a `data.stale` object naming the source
    and

    when the copy was taken — the answer is real, but may be out of date.
  contact:
    name: Dataville Support
    email: support@dataville.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
servers:
  - url: https://api.dataville.com
    description: Production
security:
  - ApiKeyAuth: []
tags:
  - name: Data sources
    description: Keyword search and article lookup across every supported dataset.
  - name: Export and SQL
    description: Bulk CSV/Parquet/DuckDB download and SELECT-only SQL over the datasets.
  - name: Connected sheets
    description: Connect a Google Sheet and query it alongside the public datasets.
  - name: Usage
    description: |-
      Usage and quota for your API key (or your IP when anonymous). Keys
      are created and revoked from the dashboard's **API Keys** page.
paths:
  /{source}/{keywords}:
    get:
      tags:
        - Data sources
      summary: Search a data source
      description: >
        Search any supported data source by keyword and return the single most

        relevant result. This is the primary endpoint of the API.


        Supported `source` values (aliases in parentheses): `wiki`
        (`wikipedia`),

        `census`, `arxiv`, `gutenberg`, `fooddata`, `paperswithcode`, `edgar`

        (`sec`, `sec-edgar`), `news` (`frontpage-news`), `stackexchange`

        (`stackoverflow`, `stack-exchange`), `pypi`, `openalex`.


        `keywords` is free text and may contain spaces and slashes; URL-encode
        it.


        ```bash

        curl -H "Authorization: Bearer $DATAVILLE_API_KEY" \
          "https://api.dataville.com/arxiv/attention%20is%20all%20you%20need"
        ```
      operationId: searchSource
      parameters:
        - $ref: '#/components/parameters/Source'
        - $ref: '#/components/parameters/Keywords'
        - $ref: '#/components/parameters/Summary'
        - $ref: '#/components/parameters/TokenQuery'
      responses:
        '200':
          description: The most relevant result for the query.
          headers:
            X-Credits-Remaining:
              $ref: '#/components/headers/XCreditsRemaining'
            X-Credit-Cost:
              $ref: '#/components/headers/XCreditCost'
            X-RateLimit-Limit:
              $ref: '#/components/headers/XRateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/XRateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/XRateLimitReset'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSuccessResponse'
              examples:
                arxiv:
                  summary: An arXiv paper
                  value:
                    status: success
                    account_state: authenticated
                    data:
                      id: '2301.00001'
                      title: Attention Is All You Need
                      body: |-
                        Authors: Ashish Vaswani, Noam Shazeer
                        Published: 2017-06-12
                        Summary: The dominant sequence transduction models...
                      source: arxiv
                      language: en
                      last_updated: '2017-06-12T00:00:00Z'
                      entities:
                        - transformer
                        - attention
                        - machine translation
                      metadata:
                        arxiv_id: '1706.03762'
                        categories:
                          - cs.CL
                          - cs.LG
                        pdf_url: https://arxiv.org/pdf/1706.03762
                    usage:
                      requests_remaining: 4821
                      request_limit: 5000
                      credits_total: 29
                      credits_remaining: 24.11
                      credits_used: 4.89
                      request_cost: 0.005
                stale:
                  summary: >-
                    Served from Dataville's stored copy while the upstream is
                    down
                  value:
                    status: success
                    account_state: authenticated
                    data:
                      id: '2301.00001'
                      title: Attention Is All You Need
                      body: 'Authors: Ashish Vaswani…'
                      source: arxiv
                      language: en
                      last_updated: '2017-06-12T00:00:00Z'
                      entities: []
                      metadata:
                        served_from_cache: true
                        cached_at: '2026-08-24T09:12:00Z'
                      stale:
                        message: >-
                          arxiv is unavailable right now, so this result comes
                          from our stored copy and may be out of date or
                          incomplete. Nothing is wrong with your query.
                        cached_at: '2026-08-24T09:12:00Z'
                    usage:
                      requests_remaining: 49
                      request_limit: 50
        '400':
          description: Unsupported source, or missing source/keywords.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataErrorResponse'
              example:
                status: error
                account_state: anonymous
                data:
                  error: >-
                    Unsupported data source: "foo" is not one we offer, so
                    nothing was searched and you were not charged. Use one of
                    these source ids instead: wiki, wikipedia, census, arxiv,
                    gutenberg, fooddata, paperswithcode, edgar, sec, sec-edgar,
                    news, frontpage-news, stackexchange, stackoverflow,
                    stack-exchange, pypi, openalex.
                  code: UNSUPPORTED_SOURCE
        '402':
          $ref: '#/components/responses/InsufficientCredit'
        '404':
          description: No results found for the query in this source.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataErrorResponse'
              example:
                status: error
                account_state: anonymous
                data:
                  error: >-
                    No results found for "zzzzzz" in arxiv. Nothing went wrong
                    and you were not charged — try different or broader
                    keywords, or another source.
                  code: NOT_FOUND
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/DataInternalError'
        '503':
          $ref: '#/components/responses/UpstreamUnavailable'
components:
  parameters:
    Source:
      name: source
      in: path
      required: true
      description: Data source name or alias.
      schema:
        type: string
        enum:
          - wiki
          - wikipedia
          - census
          - arxiv
          - gutenberg
          - fooddata
          - paperswithcode
          - edgar
          - sec
          - sec-edgar
          - news
          - frontpage-news
          - stackexchange
          - stackoverflow
          - stack-exchange
          - pypi
          - openalex
      example: arxiv
    Keywords:
      name: keywords
      in: path
      required: true
      description: URL-encoded search terms. May contain spaces and slashes.
      schema:
        type: string
      example: attention%20is%20all%20you%20need
    Summary:
      name: summary
      in: query
      required: false
      description: Truncate `data.body` to the first 100 characters.
      schema:
        type: boolean
        default: false
    TokenQuery:
      name: token
      in: query
      required: false
      description: |
        API key as a query parameter, for clients that cannot set an
        `Authorization` header (DuckDB WASM, the DuckDB CLI). Prefer the header
        wherever possible — query strings end up in logs.
      schema:
        type: string
  headers:
    XCreditsRemaining:
      description: Remaining credit balance, in USD.
      schema:
        type: number
        format: float
    XCreditCost:
      description: Credit charged for this request, in USD.
      schema:
        type: number
        format: float
    XRateLimitLimit:
      description: Request limit for the current window (anonymous callers).
      schema:
        type: integer
    XRateLimitRemaining:
      description: Requests remaining in the current window.
      schema:
        type: integer
    XRateLimitReset:
      description: When the window resets.
      schema:
        type: string
    RetryAfter:
      description: Seconds to wait before retrying, when known.
      schema:
        type: integer
  schemas:
    DataSuccessResponse:
      type: object
      properties:
        status:
          type: string
          enum:
            - success
        account_state:
          type: string
          enum:
            - authenticated
            - anonymous
        data:
          $ref: '#/components/schemas/DataSourceResult'
        usage:
          $ref: '#/components/schemas/Usage'
    DataErrorResponse:
      type: object
      description: >
        The data-route error envelope. `data.error` is written for the person
        who

        triggered it and is safe to display verbatim; branch on `data.code`.
      properties:
        status:
          type: string
          enum:
            - error
        account_state:
          type: string
          enum:
            - authenticated
            - anonymous
        data:
          type: object
          properties:
            error:
              type: string
            code:
              type: string
              enum:
                - UPSTREAM_RATE_LIMITED
                - UPSTREAM_UNAVAILABLE
                - UPSTREAM_FORBIDDEN
                - UPSTREAM_BAD_RESPONSE
                - SOURCE_UNAVAILABLE
                - INTERNAL_ERROR
                - INVALID_URL
                - INVALID_REQUEST
                - UNSUPPORTED_SOURCE
                - NOT_FOUND
    DataSourceResult:
      type: object
      description: The common shape every data source returns.
      properties:
        id:
          type: string
          description: Source-specific identifier.
        title:
          type: string
        body:
          type: string
          description: |
            Human- and LLM-readable text: newline-delimited `Key: value` lines.
            Structured values live in `metadata`.
        source:
          type: string
          example: arxiv
        language:
          type: string
          example: en
        last_updated:
          type: string
          format: date-time
        entities:
          type: array
          items:
            type: string
        metadata:
          type: object
          additionalProperties: true
          description: Structured, source-specific fields.
        stale:
          $ref: '#/components/schemas/StaleNotice'
        onboarding:
          type: object
          description: Present only on a new anonymous session's first response.
          properties:
            message:
              type: string
    Usage:
      type: object
      properties:
        requests_remaining:
          type: integer
        request_limit:
          type: integer
        credits_total:
          type: number
          format: float
          description: Monthly credit grant in USD. Metered callers only.
        credits_remaining:
          type: number
          format: float
        credits_used:
          type: number
          format: float
        request_cost:
          type: number
          format: float
          description: Credit charged for this request, in USD.
    InsufficientCreditResponse:
      type: object
      properties:
        status:
          type: string
          enum:
            - error
        account_state:
          type: string
          example: authenticated
        error:
          type: string
          example: insufficient_credit
        data:
          type: object
          properties:
            error:
              type: string
            code:
              type: string
              enum:
                - INSUFFICIENT_CREDIT
        credits:
          type: object
          properties:
            remaining_usd:
              type: number
              format: float
            request_cost_usd:
              type: number
              format: float
    StaleNotice:
      type: object
      description: >
        Present when the upstream source was unavailable and the result came
        from

        Dataville's stored copy instead. The answer is real but may be out of
        date.
      properties:
        message:
          type: string
        cached_at:
          type: string
          format: date-time
          nullable: true
  responses:
    InsufficientCredit:
      description: Monthly credit exhausted — upgrade, top off, or wait for the reset.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/InsufficientCreditResponse'
    RateLimited:
      description: Anonymous request limit exceeded (50 per 24 hours per IP).
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/XRateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/XRateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/XRateLimitReset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DataErrorResponse'
    DataInternalError:
      description: Something went wrong on Dataville's side.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DataErrorResponse'
    UpstreamUnavailable:
      description: >
        The upstream source refused or failed the request, and no stored copy
        could

        answer it. Not caused by the caller, and no credit was used.
      headers:
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DataErrorResponse'
          example:
            status: error
            account_state: authenticated
            data:
              error: >-
                arXiv is refusing requests right now, so this search could not
                be completed. This happens on arXiv's side when their service is
                under load — it is not a limit on your account and not caused by
                anything you did. No credit was used. Try again in about 2
                minutes.
              code: UPSTREAM_RATE_LIMITED
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      description: >
        A Dataville API key, sent as `Authorization: Bearer dataville_...`.
        Clients

        that cannot set headers may pass the same key as `?token=`.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.