Convert Endpoints

Conversion is part of All tools. A start needs the relevant scope and enough credits, and convert.file must be available in /v1/health. Free credits also follow the free limits: free accounts and guests may convert only their authorized, scanned sources up to 2 MiB.

Office and PDF converters run without network access in an isolated filesystem with bounded time, memory/address space, process count and output size. If the required isolation cannot start, conversion is unavailable (provider_unavailable) and converter work is not charged. Unsupported/empty documents and conversion failures retain their documented settlement rules; isolation does not guarantee every document is convertible.

Convert endpoints create billable asynchronous operations that transform a scanned stored file or reusable operation artifact into Markdown, plain text, or safe HTML. The converted output is stored as a protected operation artifact.

This endpoint is preview. Preview means the contract may still evolve before stable release.

Shared Access

  • Access: Paid plans that include this family, or free credits (guest trial or verified account) within the free limits.
  • Operation family: Conversion
  • Scope: api:convert:write
  • Idempotency: Idempotency-Key header required for live requests
  • Sources: scanned file_id or customer-visible reusable artifact_id

Unsupported fields are rejected with validation_failed. Convert endpoints do not accept raw file bytes, URLs, provider task ids, storage paths, or bulk export options.

POST/v1/convert/file

Creates a file conversion operation.

Request

{
  "source": {
    "type": "file_id",
    "id": "fil_01jz7h0a1b2c3d4e5f6g7h8j"
  },
  "output_format": "markdown",
  "include_source_metadata": true,
  "cleanup": "none"
}

Curl example:

curl -X POST https://www.chab.ai/v1/convert/file \
  -H "Authorization: Bearer CHAB_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: convert-file-001" \
  -d '{
    "source": {
      "type": "file_id",
      "id": "fil_01jz7h0a1b2c3d4e5f6g7h8j"
    },
    "output_format": "markdown"
  }'

CLI-shaped client example:

convert file fil_01jz7h0a1b2c3d4e5f6g7h8j \
  --source-type file_id \
  --output-format markdown \
  --idempotency-key convert-file-001 \
  --wait

Fields:

  • source.type: required file_id or artifact_id. A file_id must be in the available scanned state; both source types remain subject to current token and project authority.
  • source.id: required source identifier.
  • output_format: required markdown, text, or safe_html.
  • dry_run: optional boolean. Defaults to false.
  • include_source_metadata: optional boolean. Defaults to true.
  • cleanup: optional string. Only none is accepted.
  • callback_url, callback_secret, callback_events, and callback_notify_on_expiration: optional one-off operation callback fields.

Supported Matrix

Source category Markdown Text Safe HTML
Plain text Yes Yes Yes
Markdown Yes Yes Yes
HTML Yes Yes Yes
Word (DOCX, DOC), OpenDocument text (ODT), RTF Yes Yes Yes
Spreadsheets (XLSX, XLS, ODS) Yes Yes Yes
CSV and TSV Yes Yes Yes
Slide decks (PPTX, PPT, ODP) Yes Yes Yes
E-books (EPUB) Yes Yes Yes
PDF with extractable text Yes Yes No

How the structure carries over:

  • Spreadsheets: every sheet becomes a table under a heading with the sheet's name, in workbook order. CSV and TSV files become one table. Cells show the value as displayed in the sheet. Each table keeps its header row and the first 1,000 data rows and the first 50 columns; when rows are cut, the output says so under the table and the result carries a result_truncated warning.
  • Slide decks: every slide becomes a section, Slide 3: Title, with the slide's text as a list. Speaker notes are not included.
  • E-books: the chapters in reading order, with headings, lists and emphasis. Styles, scripts and images are dropped.
  • Macro-enabled Office files (DOCM, XLSM, PPTM) are refused at upload, and macros in other files never run.

Unsupported source categories return unsupported_file_type. Unsupported source/output pairs return unsupported_conversion_pair.

An eligible source that exceeds the conversion limit returns the stable source_too_large error code. This replaces the earlier field-only validation_failed response for oversized conversion artifacts.

Safe HTML output uses an allowlist suitable for display or storage. It removes scripts, styles, form controls, images, embedded media, external resource loads, event handlers, classes, inline style, and unsafe link protocols.

Pricing

Conversion pricing is based on Chab's trusted source metadata, not on customer-supplied fields.

Source category Credits
Plain text, Markdown, HTML, CSV or TSV 5
Word, Excel, PowerPoint, OpenDocument, RTF or EPUB 15
PDF with extractable text 20

Validation failures before converter work are not charged. A PDF that has no extractable text, or a spreadsheet, deck or book with nothing to read, fails with unsupported_file_content and releases the hold. Converter timeouts or failures after conversion work starts can be charged up to the reserved estimate.

See Credits and Billing.

Async Response

Live requests return 202 Accepted with the standard operation envelope:

{
  "operation": {
    "id": "op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
    "status": "queued",
    "operation_key": "convert.file",
    "family": "convert",
    "status_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K",
    "result_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K/result",
    "estimated_credits": 5,
    "result_available": false,
    "warnings": []
  },
  "meta": {
    "request_id": "req_123",
    "credits": {
      "estimated": 5,
      "reserved": 5,
      "currency": "credit"
    }
  }
}

Poll the operation status URL until it reaches a terminal state, or fetch the result URL after result_available becomes true.

Dry Run

Set dry_run: true to validate request shape, source metadata, plan access, limits, provider readiness, callback shape, budget, spend threshold, and credit availability without creating an operation.

Dry runs do not require or persist an idempotency key, do not reserve credits, do not read source content, and do not create operation rows, callback secrets, artifacts, provider tasks, usage counters, or rate-bucket hits.

{
  "source": {
    "type": "artifact_id",
    "id": "art_01JZ7H0A1B2C3D4E5F6G7H8J9K"
  },
  "output_format": "text",
  "dry_run": true
}

Dry-run response:

{
  "data": {
    "operation_key": "convert.file",
    "family": "convert",
    "estimated_credits": 5,
    "currency": "credit",
    "source": {
      "type": "artifact",
      "id": "art_01JZ7H0A1B2C3D4E5F6G7H8J9K",
      "mime_type": "text/markdown",
      "source_format": "markdown",
      "source_state": "available",
      "byte_size": 4096,
      "checksum": "sha256:example",
      "filename": "brief.md"
    },
    "output_format": "text",
    "cleanup": "none",
    "include_source_metadata": true,
    "callback": {
      "requested": false,
      "enabled": false,
      "url": null,
      "events": [],
      "notify_on_expiration": false,
      "secret_staged": false
    },
    "live_request": {
      "requires_idempotency_key": true
    }
  },
  "meta": {
    "request_id": "req_123",
    "dry_run": true
  }
}

Result And Artifact

Successful conversion results include conversion facts and one customer-visible artifact with role converted_output.

{
  "data": {
    "result": {
      "output_format": "markdown",
      "conversion_method": "markdown",
      "output_mime_type": "text/markdown",
      "output_byte_size": 2048,
      "output_checksum": "sha256:example",
      "artifact_role": "converted_output",
      "confidence": 1,
      "source": {
        "type": "artifact",
        "id": "art_01JZ7H0A1B2C3D4E5F6G7H8J9K",
        "mime_type": "text/markdown",
        "source_format": "markdown",
        "source_state": "available",
        "byte_size": 4096,
        "checksum": "sha256:source",
        "filename": "brief.md"
      }
    },
    "artifacts": [
      {
        "id": "art_01JZ7H0A1B2C3D4E5F6G7H8J9K",
        "type": "text",
        "role": "converted_output",
        "mime_type": "text/markdown",
        "byte_size": 2048,
        "checksum": "sha256:example",
        "filename": "brief.md",
        "metadata_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K/artifacts/art_01JZ7H0A1B2C3D4E5F6G7H8J9K",
        "download_url": "/v1/operations/op_01JZ7H0A1B2C3D4E5F6G7H8J9K/artifacts/art_01JZ7H0A1B2C3D4E5F6G7H8J9K/download",
        "expires_at": "2026-07-17T12:00:00+00:00"
      }
    ],
    "warnings": [],
    "result_expires_at": "2026-07-17T12:00:00+00:00"
  },
  "meta": {
    "request_id": "req_123"
  }
}

Download the converted file through the artifact download_url before expires_at. Artifact metadata and downloads require bearer authentication.

For a conversion created through hosted MCP, use chab_operation_artifact with content: "inline" for paged text, following next_offset, or content: "link" for a downloadable file. See Hosted MCP.

When include_source_metadata is false, the result omits the source object from data.result; artifact metadata remains available.

Source State Errors

Source references use the shared artifact-input behavior. Missing artifacts, cross-team artifacts, artifacts the key cannot read, and artifacts whose stored bytes are no longer readable return not_found without disclosing which condition applied.

Code HTTP Retry Chargeable What to do
not_found 404 No No Check the artifact id and make sure it belongs to the same team and token context.
artifact_expired 410 No No Use a non-expired artifact.

Conversion Errors

Code HTTP Retry Chargeable What to do
unsupported_file_type 422 No No Use a supported source category.
unsupported_conversion_pair 422 No No Pick an output format supported by the source category.
unsupported_file_content 422 No No Use a file with extractable text.
conversion_timeout 504 Yes Yes, after work starts Retry later or reduce source complexity.
conversion_failed 502 No Yes, after work starts Check the source and output format before retrying.

artifact_creation_failed can also occur if Chab cannot persist the converted artifact. In that case the hold is released because the output is not available.

Callbacks

Callbacks use the standard operation callback contract. Terminal callback payloads use the same operation shape as polling, including operation.status, operation.public_error_code, settlement facts when available, and artifact references when the result succeeded. Use the operation result URL to download the retained converted artifact.