Skip to content
ParsedMail

Errors and limits

ParsedMail API errors return a JSON body with an error type and a readable message, plus a matching HTTP status. Usage counts parsed emails and attachment pages per monthly period. Duplicates, blocked senders, forwarding confirmations and replays of counted emails are free, and deleting never gives usage back.

Error format

Errors raised by the API have one shape:

HTTP/1.1 404 Not Found
Content-Type: application/json

{"error": {"type": "not_found", "message": "No inbox with this id."}}

Branch on type, show message to people. API errors use this shape, also for a missing key, an unknown endpoint and the rate limit, with or without an Accept header, and a wrong HTTP method returns 405 with type method_not_allowed. A request that fails validation adds a fields object with the messages per parameter:

HTTP/1.1 422 Unprocessable Content

{"error": {"type": "invalid_request", "message": "The name field is required.", "fields": {"name": ["The name field is required."]}}}

Over the rate limit the answer is 429 with type rate_limited and a Retry-After header in seconds.

Error types and HTTP statuses

HTTPTypeWhenWhat to do
401unauthenticatedNo key, wrong key, revoked keyCheck the Authorization: Bearer header
402plan_limitInbox count of the plan reached on POST /inboxes; monthly, page or daily limit reached on POST /parseWait for the next period or move to a higher plan
403forbiddenThe key lacks the scope, for example This API key lacks the "write" permission.Create a key with the scope
403forbiddenThe person who created the key no longer belongs to its workspace: This API key no longer has access to its workspace.Create a new key from a current member
404not_foundInbox, schema or email id not in this workspace, or an unknown endpointCheck the id, the path and the workspace of the key
409inbox_pausedEmail posted to a paused inboxResume the inbox in the dashboard and send the email again
410purgedReplay of an email whose raw content was deleted under retentionThe JSON result stays available; resubmit the original if you still have it
413too_largeRaw MIME over 25 MB, or a JSON body over about 33.4 MB (25 MB of files after base64)Send fewer or smaller attachments
422invalid_schemaUnknown type, duplicate key, enum with fewer than 2 options, table without columns, more than 60 fields, or a description with no recognizable fieldsFix the field definitions; the message names the field
422empty_emailNo body text and no attachmentsCheck how the message is encoded in the request
422invalid_requestA required parameter is missing or too long, since is not an ISO 8601 date-time, starting_after is not an email of this workspace, or attachment content is not base64Read message and fields
429rate_limitedMore than 120 requests per minute for the workspaceWait Retry-After seconds
503parser_unavailableThe parser could not answer during POST /parse; nothing was countedRetry after a short pause with backoff

Asynchronous problems do not become HTTP errors. An email submitted to an inbox is accepted with 202 and its later status, such as over_limit or failed, shows in the log and in GET /v1/emails/{id}, with the reason in the dashboard. The statuses are listed in sending emails.

Plan limits

LimitSandboxStarterGrowthScale
PriceFree, once$49/mo or $24/mo billed yearly$149/mo or $74/mo billed yearly$499/mo or $249/mo billed yearly
Emails10 in total1,000 a month5,000 a month25,000 a month
Attachment pagesAttachments of 1 page, no scans300 a month2,000 a month10,000 a month
Inboxes1525Unlimited
Seats11520
Raw email retention7 days30 days90 days365 days, configurable, or zero
Webhooks with retriesNoYesYesYes
Review queue, classification, failure alertsNoNoYesYes
Custom inbound domain, SSO, audit log, priority queueNoNoNoYes

Limits are monthly, also on yearly billing, in periods that start on the day your subscription started. The sandbox allowance is one-time and never renews. Moving to a higher plan takes effect at once and the difference is charged pro rata immediately. Seats count the owner, the members and pending invitations; an invitation beyond the plan's seats is refused until you move to a higher plan or remove someone. Other fixed limits:

  • One email up to 25 MB: raw MIME up to 25 MB, JSON up to 25 MB of files after base64 (about 33.4 MB of request body); up to 20 attachments stored and 8 files read per email
  • Schemas up to 60 fields, tables up to 20 columns, enums up to 30 options
  • Up to 20 webhook endpoints per workspace; 15 second timeout per attempt
  • API rate limit 120 requests per minute per workspace; list pages up to 100 emails

What counts toward usage

One email is counted when it is parsed, that is when the model has read it and a result exists. Its attachment pages are counted at the same moment on paid plans: a PDF page is one page, a text, CSV or similar file is one page per about 3,000 characters, an image is one page.

CountedNot counted
Every parsed email, also when it later goes to review or is rejected thereDuplicates (same Message-ID or same sender, subject and body within 30 days)
Every POST /v1/parse call that returns a resultEmails from senders not on the allowed list
Every Test run in the schema editorGmail and Outlook forwarding confirmation emails
The first parse of a replayed email that was never parsed, for example one stored as over_limitReplays of emails that were already counted
Emails stored as over_limit, and emails that failed before parsing (paused inbox, no schema, parser error)
Webhook deliveries, retries and test events

Usage is consumption, not a count of what you keep. Deleting an email, a schema or an inbox never gives emails or pages back. Check usage any time with GET /v1/usage from the API reference.

At the limit, the 80 percent alert and the daily safety brake

When the workspace reaches 80 percent of its monthly emails, the owner gets one email for that period. When the email or page limit is reached, parsing pauses: new emails are still received and stored with status over_limit, nothing is lost, and the owner gets an email that parsing has paused (at most once a day). After the next period starts or after an upgrade, replay those emails from the log or with POST /v1/emails/{id}/replay. An email that needs more pages than are left is stored as over_limit as a whole.

A forwarding loop, for example two mailboxes forwarding to each other, can burn a month of emails in an hour. Paid plans therefore have a daily safety brake at 30 percent of the monthly email limit in one day, far above a normal busy day:

PlanEmails per day before the brake
Starter300
Growth1,500
Scale7,500

Past the brake, emails are stored as over_limit with the reason "Daily safety limit reached (a forwarding loop protection)" and parsing resumes the next day at 00:00 UTC. Allowed senders on each inbox, described in inboxes and forwarding, are the best protection against loops.

Retention of raw email

ParsedMail keeps the raw message (body, headers and attachment files) for the retention period of your plan, then deletes it in an hourly cleanup. The parsed JSON, the confidence scores, the subject, the sender and the attachment names stay, so the log and the API keep working.

PlanRaw email kept
Sandbox7 days
Starter30 days
Growth90 days
Scale365 days by default, any value from 1 to 365 days, or zero retention

With zero retention on Scale, the raw message is deleted at the first cleanup after processing, once it is at least 10 minutes old. Whatever the setting, the cleanup never touches an email that is still received, processing or needs_review, so reviewers always see the original next to the values; it is deleted after the review. After deletion an email cannot be replayed (410 purged). Email content is never used to train models. More on data handling is on the security page.

Frequently asked questions

Do I get usage back when I delete emails?

No. Usage counts what was parsed in the period. Deleting an email, a schema or an inbox never returns emails or pages.

What happens to emails that arrive over my limit?

They are stored with status over_limit and not parsed. Replay them after an upgrade or when the next period starts; each one counts once when it is parsed.

Is a duplicate email charged?

No. A duplicate within 30 days in the same inbox gets status duplicate, links to the original with duplicate_of and is not counted.

Why did parsing stop before my monthly limit?

The daily safety brake stops parsing for the rest of the UTC day when a workspace parses far more than usual, which is the typical sign of a forwarding loop. Emails are stored as over_limit and can be replayed.

Should I retry a 503 from the parse endpoint?

Yes. parser_unavailable is temporary and the failed call is not counted. Retry with a growing pause, for example after 2, 10 and 30 seconds.

Related