# Collect statements from applicants

> Send an applicant a hosted upload link. They upload without an account, and every file is read and delivered to you.

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

---

A collection is a hosted upload page with its own link. Send the link to an applicant; they upload their statements without an account, and each file is read and delivered to you as a document.

## How it works

1. Create a collection with `POST /api/v1/collections`, or in the console's Collections page.
2. Send the applicant its `url`, by email, SMS or inside your own app.
3. They open the page, read your message and upload up to 24 files: PDFs, photos or exports.
4. Each file is read as it lands. You receive `document.succeeded` or `document.failed` for each one.
5. They press the button saying they have sent everything. You receive `collection.submitted`, and they go to your `redirectUrl` if you set one.

## Create one

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"])
```

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": []
}
```

`name` is required: who the statements are for, as you will recognise it in the console. `message` is shown to the applicant. `metadata` is copied onto every document uploaded. The link expires after `expiresInDays`, from 1 to 30, default 14. Every field is on [Collections](https://statementbear.com/docs/api/collections).

## What the applicant sees

- Your account's name, as set in the console, asking for their statements.
- Your `message`, above an upload box.
- Each file's name and whether it was read. Nothing from inside their statements is shown back.
- A button to say they have sent everything.

No account, no sign-in. The link is their only access, so send it only to them.

## Collect the results

- **Webhooks.** Each document's events carry `collection` set to the collection's id and the collection's `metadata`. See [Webhooks](https://statementbear.com/docs/webhooks).
- **Listing.** `GET /api/v1/documents?collection=col_...` returns every document uploaded through it, newest first.
- **The collection.** `GET /api/v1/collections/{id}` lists the uploaded document ids in `documents`.

## Original files

A collection upload keeps its original file, because you never had a copy. Download it with `GET /api/v1/documents/{id}/file`. It is deleted with the document, when your retention period ends or when you delete the document. See [Security and data retention](https://statementbear.com/docs/security).

## Billing

Each upload is billed per page to your account, like any document. When your account cannot take more pages (no free pages left and no payment method, or the monthly cap reached), the upload is refused and the applicant is told you cannot receive statements right now. Nothing is read or charged.

## Passwords

The hosted page does not take passwords. A password-protected PDF is refused with a message asking the applicant to remove the password and send it again.

## Closing and expiry

- `DELETE /api/v1/collections/{id}` closes the link. It stops taking uploads at once.
- At `expiresAt` the link stops working on its own.
- Documents already uploaded stay until your retention period ends, whatever happens to the collection.

## Testing

A collection created with a test key has an id starting `col_test_` and a working hosted page. Every upload returns the `bank` fixture, events go to your test endpoints, and nothing is billed.

---

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