# Collections

> POST, GET and DELETE /api/v1/collections: create, list, fetch and close hosted upload links, and the collection object.

Section: API reference
Source: https://statementbear.com/docs/api/collections
Product: StatementBear statement parsing API, $0.08 per page, 200 pages free.

---

Create, list, fetch and close hosted upload links. The guide is [Collect statements from applicants](https://statementbear.com/docs/collections).

| Method and path | Does |
| --- | --- |
| `POST /api/v1/collections` | Creates a collection. [Create a collection](#create-a-collection). |
| `GET /api/v1/collections` | Lists collections, newest first. [List collections](#list-collections). |
| `GET /api/v1/collections/{id}` | Returns one. [Get a collection](#get-a-collection). |
| `DELETE /api/v1/collections/{id}` | Closes one. [Close a collection](#close-a-collection). |

Authenticated like every endpoint. A key sees only collections of its own mode. A collection made with a test key returns fixtures for every upload and is never billed.

## Create a collection

`POST /api/v1/collections`

A JSON body (`Content-Type: application/json`), or a form.

| Field | Required | Value |
| --- | --- | --- |
| `name` | Yes | Who the statements are for, as you will recognise it. Up to 80 characters. |
| `message` | No | Shown to the applicant above the upload box. Up to 600 characters. |
| `metadata` | No | A JSON object of strings, copied onto every document uploaded. Same limits as a document's. |
| `redirectUrl` | No | An `https` URL the applicant is sent to after they submit. |
| `expiresInDays` | No | A whole number from 1 to 30. Default 14. |

cURL:

```bash
curl -X POST https://statementbear.com/api/v1/collections \
  -H "Authorization: Bearer $STATEMENTBEAR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Smith remortgage",
    "message": "Please upload your last three months of statements for every current account.",
    "redirectUrl": "https://broker.example.com/applications/8841/done",
    "metadata": { "applicationId": "app_8841" },
    "expiresInDays": 14
  }'
```

Node.js:

```javascript
const res = await fetch("https://statementbear.com/api/v1/collections", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.STATEMENTBEAR_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "Jane Smith remortgage",
    message: "Please upload your last three months of statements for every current account.",
    redirectUrl: "https://broker.example.com/applications/8841/done",
    metadata: { applicationId: "app_8841" },
  }),
});

const collection = await res.json();
await emailApplicant(collection.url);
```

Python:

```python
import os, requests

res = requests.post(
    "https://statementbear.com/api/v1/collections",
    headers={"Authorization": f"Bearer {os.environ['STATEMENTBEAR_KEY']}"},
    json={
        "name": "Jane Smith remortgage",
        "message": "Please upload your last three months of statements for every current account.",
        "redirectUrl": "https://broker.example.com/applications/8841/done",
        "metadata": {"applicationId": "app_8841"},
    },
    timeout=30,
)
collection = res.json()
email_applicant(collection["url"])
```

Returns `201` with the collection. A missing or out-of-range field returns `400 invalid_collection`, naming it; a body that is not a JSON object or a form returns `400 invalid_body`.

201 Created:

```json
{
  "id": "col_3b9e0c7a51d24f88a6c1e290",
  "object": "collection",
  "livemode": true,
  "created": 1785372094,
  "name": "Jane Smith remortgage",
  "message": "Please upload your last three months of statements for every current account.",
  "url": "https://statementbear.com/r/q7Hx2LmN0pRtVb9kZc4WdYe1",
  "status": "open",
  "submittedAt": null,
  "expiresAt": 1786581694,
  "redirectUrl": "https://broker.example.com/applications/8841/done",
  "metadata": { "applicationId": "app_8841" },
  "documents": []
}
```

## List collections

`GET /api/v1/collections`

Newest first, as `{ "object": "list", "data": [...], "hasMore": false }`. Takes `limit` (1 to 100, default 20) and `starting_after` (a collection `id`), like the document list.

## Get a collection

`GET /api/v1/collections/{id}`

The collection, with `documents` listing every upload so far. An unknown id returns `404 collection_not_found`.

## Close a collection

`DELETE /api/v1/collections/{id}`

Stops the link taking uploads and returns the collection with `status: "closed"`. Documents already uploaded are kept for your retention period. Closing twice returns the same collection.

## The collection object

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | col_ followed by 24 hex characters. col_test_ on a test key. Filter documents by it with GET /api/v1/documents?collection=. |
| `object` | `"collection"` | Always collection. Lists and webhook events wrap collections, so the type is on every object. |
| `livemode` | `boolean` | False when a test key created it. Uploads to a test collection return the bank fixture and are never billed. |
| `created` | `number` | When it was created. Unix seconds. expiresAt and submittedAt use the same units. |
| `name` | `string` | Who the statements are for, as you will recognise it. Required. Up to 80 characters. Shown in your console. |
| `message` | `string \| null` | Shown to the uploader above the upload box. Up to 600 characters. Say which accounts and months you need. |
| `url` | `string` | The hosted page to send the applicant. The link is the applicant's only access, so send it only to them. It stops taking uploads when the collection is closed or expires. |
| `status` | `"open" \| "submitted" \| "expired" \| "closed"` | open until the applicant says they have sent everything. submitted once they press the button on the page. expired after expiresAt. closed after you DELETE it. A closed or expired collection takes no more uploads. |
| `submittedAt` | `number \| null` | When the applicant said they had sent everything. The collection.submitted event is sent at the same moment. |
| `expiresAt` | `number` | When the link stops working. Unix seconds. Set by expiresInDays: 1 to 30, default 14. |
| `redirectUrl` | `string \| null` | Where the applicant is sent after they submit. An https URL. Without one, the page thanks them and they close it. |
| `metadata` | `object` | Your own key-value pairs, copied onto every document uploaded. Same limits as a document's metadata. |
| `documents` | `string[]` | The doc_ ids of every file uploaded so far, oldest first. Up to 24. Fetch each with GET /api/v1/documents/{id}. |

## Limits

- Up to 24 files per collection, each up to 50MB.
- No passwords on the hosted page: a protected PDF is refused with a message asking the applicant to remove it.
- Uploads are billed per page like any document, and refused while your account cannot take more pages.

---

All documentation: https://statementbear.com/docs/llms.txt
Questions: support@statementbear.com
