---
title: "Create up to 50 plain notes in one call"
method: POST
path: "/notes/bulk"
tags: ["notes"]
---

# Create up to 50 plain notes in one call

`POST /notes/bulk`

## Request

- Base URL: `https://freshjots.com/api/v1`
- URL: `https://freshjots.com/api/v1/notes/bulk`
- Auth: HTTP bearer

All-or-nothing: any row that fails validation refuses the whole batch with the failing rows listed under `error.failed`.

## Headers

- `Idempotency-Key` string

## Request body

- BulkCreateBody
  - `notes` object[], required
    - `title` string
    - `plain_body` string, required
    - `format` 'plain'
    - `append_only` boolean
    - `client_encrypted` boolean
    - `folder_id` integer, nullable
    - `append_deadline_hours` integer, nullable
    - `alert_email` string, nullable
    - `match_pattern` string, nullable
    - `webhook_url` string, nullable
    - `webhook_secret` string
    - `webhook_format` 'generic' | 'slack' | 'discord' | 'google_chat' | 'mattermost' | 'rocket_chat'
    - `tsa_token` string: Base64 RFC 3161 timestamp token over the exact plain_body (create only).
    - `tsa_url` string

## Response `201`

Every note created.

- BulkCreateResult
  - `created` Note[], required
    - `id` integer, required
    - `hashid` string, required
    - `filename` string, required
    - `title` string, nullable
    - `format` 'plain' | 'rich', required
    - `folder_id` integer, nullable
    - `pinned` boolean
    - `append_only` boolean, required
    - `client_encrypted` boolean, required
    - `append_deadline_hours` integer, nullable
    - `alert_email` string, nullable
    - `match_pattern` string, nullable
    - `match_alerted_at` string, date-time, nullable
    - `last_appended_at` string, date-time, nullable
    - `alerted_at` string, date-time, nullable
    - `webhook_url` string, nullable
    - `webhook_format` 'generic' | 'slack' | 'discord' | 'google_chat' | 'mattermost' | 'rocket_chat'
    - `webhook_failure_count` integer
    - `webhook_disabled_at` string, date-time, nullable
    - `created_at` string, date-time, required
    - `updated_at` string, date-time, required
    - `plain_body` string, required: The body, or the requested slice of it; for rich notes the plain-text projection.
    - `byte_size` integer, required: Full body size in bytes, even when sliced.
    - `slice` Slice: Present only when the body was cut by tail, since or a size cap.
      - `since` integer, nullable
      - `tail` integer, nullable
      - `bytes` integer, required
      - `truncated` boolean, required

## Other responses

- `401`: Missing, invalid, revoked or expired bearer token (`unauthenticated`).
- `403`: The token's scope or plan does not allow this (`forbidden`).
- `404`: No such record in this token's scope (`not_found`).
- `409`: The Idempotency-Key was already used with a different body (`idempotency_key_conflict`).
- `413`: Over the per-note byte cap and no roll-over possible (`content_too_large`).
- `422`: One or more rows failed; nothing was created.
- `429`: Throttled (`rate_limited`); honour Retry-After.
- `503`: Backend temporarily unreachable; retry with backoff (`service_unavailable`).

---

[API](https://skmtc.dev/freshjots/apis/fresh-jots-api.md) · [All operations](https://skmtc.dev/freshjots/apis/fresh-jots-api/llms.txt) · [OpenAPI document](https://skmtc.dev/freshjots/apis/fresh-jots-api/revisions/2708284fa25a?raw)
