Skip to content
Foldbun StackDocs
中Get an API keyComing soon

Layout analysis and recognition of one document page

POST
/v1/documents/parse
curl --request POST \
--url https://api.stack.foldbun.com/v1/documents/parse \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "image": { "id": "img_3b1f0c5e9a7d42c8b6e1f0a9d8c7b6a5f4e3d2c1b0a998877665544332211000" }, "options": { "blocks": true } }'

Model paddleocr-vl (default). One request is one page image (billed per page). Multi-page PDFs are later. Layout blocks (text, title, table, formula, figure, …) are returned in reading order together with the page as Markdown (tables as HTML tables, formulas as LaTeX).

Idempotency-Key
string
>= 1 characters <= 128 characters /^[\x21-\x7e]+$/

1 to 128 printable ASCII characters. Within an account, a key is remembered for 24 hours: repeating the request with the same body returns the original response (header Idempotent-Replayed: true) without charging or running the call again. The same key with a different body is 409 idempotency_conflict. See the Overview.

One document page image.

Media typeapplication/json

Document parsing request.

object
model

Document parsing model.

string
default: paddleocr-vl
Allowed values: paddleocr-vl
image
required

One page of the document as an image.

object
>= 1 properties <= 1 properties
id

Handle returned by POST /v1/images (or by an earlier call): img_ plus the SHA-256 of the sanitized image. Valid only inside the uploading account.

string
/^img_[0-9a-f]{64}$/
url

Reserved (later). Currently 400 unsupported.

string format: uri
/^https:///
base64

Standard base64 of a JPEG, PNG or WebP file; a data: prefix is tolerated.

string
options

Optional tuning of the result.

object
blocks

Include blocks (otherwise only markdown).

boolean
default: true

Example

{
"image": {
"id": "img_3b1f0c5e9a7d42c8b6e1f0a9d8c7b6a5f4e3d2c1b0a998877665544332211000"
},
"options": {
"blocks": true
}
}

The page as Markdown and, unless disabled, its layout blocks in reading order.

Media typeapplication/json
object
id
required

Call id call_<uuid>; quote it to support.

string
model
required

Id of the model that served the call.

string
image
required

The oriented original the coordinates refer to. Absent for text-only embeddings.

object
id
required

Image handle: img_ plus the SHA-256 of the sanitized bytes.

string
/^img_[0-9a-f]{64}$/
width
required

Width of the oriented original in pixels (EXIF orientation applied).

integer
height
required

Height of the oriented original in pixels (EXIF orientation applied).

integer
bytes
required

Size of the stored image in bytes.

integer
contentType
required

Media type of the stored image (the type of the upload).

string
Allowed values: image/jpeg image/png image/webp
cost
required

Credits this call charged. 0 for failed calls and calls covered by an included daily allowance. Internal accounts are metered but not debited, so cost is then the price of the call.

number
balance
required

Account balance in credits after the call (unchanged for internal accounts).

number
timing
required

Server-side timing of this call in milliseconds. queueMs is the time from submission until a GPU node took the job (queueing, including a re-queue after a node failure); processingMs is from there until the result was back (image fetch, inference, and the node-to-server round trips). inferenceMs, imageFetchMs and serverMs break this down further. Network time between the client and the API is not included.

object
queueMs
required

Milliseconds from submission until a GPU node took the job.

integer
processingMs
required

Milliseconds from there until the result was back.

integer
inferenceMs

Model time on the GPU node as the node measured it, without the image fetch. Never larger than processingMs. Absent when the node did not report it.

integer
imageFetchMs

Time the node spent obtaining the image bytes. 0 when the image was sent with the job or the node did not need it (encode cache hit). Absent when the node did not report it.

integer
serverMs

Whole time inside the API server: request received, until just before the response is written. Includes reading the request body, image preparation, admission, queueMs, processingMs and billing settlement. Absent only in an idempotent replay of a response stored by an older server.

integer
billing

How the call was priced.

object
lines
required

One line per priced unit of the call.

Array<object>
object
unit
required

Price-book unit, as in GET /v1/models prices[].unit (for example encode_image, prompt, refine, image).

string
quantity
required

Units used.

integer
>= 1
unitPrice
required

List price of one unit.

number
amount
required

Price of the line: unitPrice * quantity, or 0 when waived. On a call that is not charged (trial, included daily allowance) lines still show the list price.

number
waived
required

True for the image-encoding fee when the node already held the encoding (cache: hit); amount is then 0 and the fee that would have applied is unitPrice * quantity.

boolean
total
required

Price of the call (sum of the line amounts, cut down to the balance when capped).

number
charged
required

Whether the account balance was debited. False for Playground trial calls and for calls covered by an included daily allowance (then pool and allowance are set); true for billed calls. Internal accounts are metered at the list price and never debited, so charged is false and total is the price.

boolean
pool
required

The pool whose included daily allowance covered the call (public or free). Null for billed calls (including calls beyond the allowance), trial calls and internal accounts.

string | null
allowance

Today’s (UTC) included calls of pool, counting this one. Present only when pool is set.

object
used
required

Calls used today (UTC), including this one.

integer
>= 1
limit
required

Included calls per UTC day.

integer
>= 1
capped

Present and true only when the price exceeded the balance and the debit was cut down to it.

boolean
pages
required

Number of pages parsed; always 1 for now.

integer
Allowed value: 1
markdown
required

The page as Markdown (tables as HTML tables, formulas as LaTeX). The blocks joined in reading order.

string
blocks

Layout blocks in reading order.

Array<object>
object
type
required

Kind of layout block.

string
Allowed values: text title table formula figure caption header footer list other
order
required

Reading order, from 0.

integer
bbox
required

Box of the block.

Array<number>
>= 4 items <= 4 items
text

Plain text of the block. Absent for blocks without text, such as a figure. A table block holds an HTML <table>; a formula block holds LaTeX delimited by $$ (display formulas) or $ (inline formulas, which layout analysis may also return as their own block, where the delimiter can be $$ as well); formulas inside running text stay in the text of their block, delimited by $.

string
markdown

Markdown of the block. Tables and formulas as in text.

string

Example

{
"image": {
"contentType": "image/jpeg"
},
"pages": 1,
"blocks": [
{
"type": "text"
}
]
}

The error envelope. The HTTP status follows the code; only retryable: true errors are worth repeating unchanged. A failed call costs 0.

Status Codes
400 invalid_request, invalid_image (the image passed the upload checks but could not be decoded), unsupported
401 unauthorized
402 insufficient_balance
403 model_locked
404 not_found, image_not_found
409 idempotency_conflict, request_in_progress
413 payload_too_large
429 rate_limited, daily_limit_reached, too_many_batches (all with Retry-After)
500 internal_error
502 upstream_error, bad_model_output
503 model_unavailable, model_busy, unavailable (all with Retry-After)
504 upstream_timeout

model_unavailable also covers a short loss of contact with the only GPU worker serving the model: for about a minute after the loss, interactive calls answer it at once with a short Retry-After (5 s), while sync and batch calls stay queued until their own deadline instead of failing.

Meaning and retry guidance for each code: Errors.

Media typeapplication/json

Body of every error response.

object
error
required

The error.

object
code
required

Stable machine-readable error code. Branch on this, not on message. Listed with the HTTP statuses under Responses.

string
message
required

Human-readable explanation. The wording can change.

string
retryable
required

True when repeating the same request unchanged can succeed.

boolean
retryAfterMs
required

Suggested wait before a retry in milliseconds; 0 when there is no hint.

integer

Example

{
"error": {
"code": "model_busy",
"message": "model sam3 is busy; retry shortly",
"retryable": true,
"retryAfterMs": 5000
}
}
Retry-After
integer
>= 1

Whole seconds to wait before retrying; present on 429 and 503.

X-Request-Id
string
/^[0-9a-f]{16}$/

Server-generated request id (16 hexadecimal characters); present on every response. Quote it when contacting support.