---
title: "Look up one field for each of up to 500 organizations in one call"
method: POST
path: "/api/v1/batch"
tags: ["Batch"]
---

# Look up one field for each of up to 500 organizations in one call

`POST /api/v1/batch`

## Request

- Base URL: `https://data.useplinth.com`
- URL: `https://data.useplinth.com/api/v1/batch`
- Auth: API key in header `X-API-Key`

The spreadsheet endpoint. Each row names an organization (an EIN, or a name to resolve) and ONE field from the published vocabulary (`GET /api/v1/batch/fields`); the values come back in the same order, each with a status that says whether it is an answer, an unresolved name, a field the key's plan does not reach, or an error. Costs one call per 50 rows rather than one per row, charged against the same allowance as every other endpoint. Rows the request cannot pay for are refused as a whole before any work is done, with the number of rows the balance does cover.

## Request body

- BatchRequest
  - `rows` BatchRow[], required: Up to 500 rows, answered in order.
    - `ein` string, nullable: EIN in any format (131837418 or 13-1837418). Either this or `name`.
    - `name` string, nullable: Organization name to resolve when no EIN is known. Matched exactly after normalizing case and punctuation; a name several organizations share answers `ambiguous` with the candidates, and `state` narrows it.
    - `state` string, nullable: Two-letter state, used only to narrow a `name` that matches in several states.
    - `field` string, required: One key from GET /batch/fields.
    - `year` integer, nullable: Filing year, for the grant-graph fields. Ignored, with a note, on fields that read the latest filing.
    - `to` string, nullable: Second EIN, for the pair fields (grants_to_*): the recipient, where the row's organization is the funder.

## Response `200`

One result per request row, in order.

- BatchResponse
  - `code` integer
  - `message` string, required
  - `x_plinth` XPlinth: Non-Candid metadata. Safe to ignore for compatibility; `unsupported` is the one to assert on.
    - `warnings` ResponseWarning[], nullable
      - `parameter` string, required
      - `severity` string, required: `caveat` informs; anything else means a filter did NOT apply.
      - `reason` string, required
    - `unsupported` string[], nullable: Parameters that did not apply. Non-empty means the answer is not the question asked.
    - `dataset` DatasetStamp: Provenance of the slice that answered. `version` is the sync signal — poll it, re-pull when it moves.
      - `source` string, nullable
      - `refresh` string, nullable
      - `polled` string, nullable: How often we LOOK for a new IRS release, as distinct from how often the IRS publishes one.
      - `reporting_lag` string, nullable: Why a figure is dated to a fiscal year rather than to today.
      - `basis` string, nullable: Grants PAID versus grants approved — the reconciliation that catches people comparing a total here to a funder's own published giving figure. Read it before filing a discrepancy.
      - `version` string, nullable: Opaque build stamp of the data slice. Changes only when the data does.
      - `generated_at` string, nullable: ISO 8601 timestamp the slice was built.
      - `license` string, nullable: Licence the source data is published under, where it carries one. Absent for public-domain sources.
      - `attribution` string, nullable: Attribution the source licence obliges you to reproduce. Present it verbatim wherever you show figures from this jurisdiction.
      - `currency` string, nullable: Currency of every amount in the response, when it is not US dollars. Amounts are never converted — they are the filing's own figures.
    - `datasets` DatasetStamp[], nullable: Every corpus this response could have drawn on, each with its own licence terms. /sql only: you write the query, so which corpus answered is not knowable per response — honour every licence listed.
      - `source` string, nullable
      - `refresh` string, nullable
      - `polled` string, nullable: How often we LOOK for a new IRS release, as distinct from how often the IRS publishes one.
      - `reporting_lag` string, nullable: Why a figure is dated to a fiscal year rather than to today.
      - `basis` string, nullable: Grants PAID versus grants approved — the reconciliation that catches people comparing a total here to a funder's own published giving figure. Read it before filing a discrepancy.
      - `version` string, nullable: Opaque build stamp of the data slice. Changes only when the data does.
      - `generated_at` string, nullable: ISO 8601 timestamp the slice was built.
      - `license` string, nullable: Licence the source data is published under, where it carries one. Absent for public-domain sources.
      - `attribution` string, nullable: Attribution the source licence obliges you to reproduce. Present it verbatim wherever you show figures from this jurisdiction.
      - `currency` string, nullable: Currency of every amount in the response, when it is not US dollars. Amounts are never converted — they are the filing's own figures.
    - `excluded` object, nullable: Per-class cost of `?exclude=`, keyed by class name, plus `overlapping` — true when classes were counted independently and therefore sum to more than the whole. /grants/summary only.
    - `unidentified` Unidentified: Grants held OUT of a recipient ranking because their recipient is not an organization.
      - `grants` integer, nullable
      - `dollars` integer, nullable
      - `note` string, nullable
      - `unavailable` string, nullable: Present only when the size could not be computed. The ranking above is unaffected.
  - `results_count` integer, required
  - `calls_charged` integer, required: Calls this request cost: one per 50 rows.
  - `results` BatchResult[], required
    - `i` integer, required: Index of the request row this answers. Results are in request order, but a client should key on this rather than on position.
    - `ein` string, nullable: The EIN the row resolved to, when it did.
    - `name` string, nullable: The organization's name, when the row resolved.
    - `field` string, required
    - `year` integer, nullable
    - `value` unknown
    - `status` string, required: ok · not_found · unresolved · ambiguous · upgrade · capped · unknown_field · invalid · error. Anything but `ok` has a `note`.
    - `note` string, nullable
    - `candidates` object[], nullable: On `ambiguous`: the organizations the name matched, each with ein, name and state.

## Other responses

- `401`: No API key, or a key we do not recognize.
- `402`: The call allowance is spent, the account is inactive, or the endpoint needs a paid plan — the message says which, and names the period it resets on (daily on free and non-profit plans, monthly on Pro).
- `422`: Validation Error

---

[API](https://skmtc.dev/useplinth/apis/plinth-grants-api.md) · [All operations](https://skmtc.dev/useplinth/apis/plinth-grants-api/llms.txt) · [OpenAPI document](https://skmtc.dev/useplinth/apis/plinth-grants-api/revisions/15273cd72ecf?raw)
