# mistral

OpenAPI spec: [https://api.payweave.app/app/app_fy1qo7pll6by4ylime4wgol8/openapi.json](https://api.payweave.app/app/app_fy1qo7pll6by4ylime4wgol8/openapi.json)

## Networks

| Name | Mode | CAIP-2 | Chain ID / Cluster |
|---|---|---|---|
| Tempo Mainnet | live | `eip155:4217` | 4217 |
| Solana Mainnet | live | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | mainnet-beta |

## Accepted Currencies

| Symbol | Name | Decimals | Network | Address |
|---|---|---|---|---|
| USDC.e | Bridged USDC (Stargate) | 6 | `eip155:4217` | `0x20c000000000000000000000b9537d11c60e8b50` |
| USDC | USD Coin (Solana) | 6 | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` |

## Endpoints (3)

### Mistral: OCR

Run Mistral OCR (mistral-ocr-latest) on a document or image URL and get markdown per page, plus optional structured annotations. Mirrors POST api.mistral.ai/v1/ocr: same request and response shape, swap only the host. Price is $0.01 per page, or $0.02 per page when any annotation option is set. pages accepts an array like [0, 1, 2] or a range string like "0,2-4"; omit it to process the whole document, in which case the service counts the PDF pages itself before quoting the price (PPTX/DOCX need explicit pages; max 1000 pages per call). Image inputs always count as one page. The body is validated before charging, and upstream failures (including pages past the end of the document) are refunded automatically. For private files, upload to storage.payweave.services first and pass the returned URL.

- Method: POST
- Path: `/ocr`
- Price: $0.01000000

**Input Schema**

```json
{
  "type": "object",
  "properties": {
    "model": {
      "type": [
        "string",
        "null"
      ],
      "description": "Mistral OCR model id. Defaults to mistral-ocr-latest."
    },
    "include_image_base64": {
      "type": [
        "boolean",
        "null"
      ],
      "description": "Return base64 image data for images extracted from the document"
    },
    "image_limit": {
      "anyOf": [
        {
          "type": "integer",
          "exclusiveMinimum": 0
        },
        {
          "type": "null"
        }
      ],
      "description": "Maximum number of images to extract"
    },
    "image_min_size": {
      "anyOf": [
        {
          "type": "integer",
          "exclusiveMinimum": 0
        },
        {
          "type": "null"
        }
      ],
      "description": "Minimum height and width, in pixels, for an image to be extracted"
    },
    "bbox_annotation_format": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "enum": [
                "text",
                "json_object",
                "json_schema"
              ]
            }
          },
          "required": [
            "type"
          ],
          "additionalProperties": true
        },
        {
          "type": "null"
        }
      ],
      "description": "Structured format for per-image bbox annotations (upstream accepts json_schema only). Setting this prices the call at the annotation rate."
    },
    "document_annotation_format": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "enum": [
                "text",
                "json_object",
                "json_schema"
              ]
            }
          },
          "required": [
            "type"
          ],
          "additionalProperties": true
        },
        {
          "type": "null"
        }
      ],
      "description": "Structured format for a whole-document annotation (upstream accepts json_schema only). Setting this prices the call at the annotation rate."
    },
    "document_annotation_prompt": {
      "type": [
        "string",
        "null"
      ],
      "description": "Optional prompt guiding structured extraction over the whole document. Requires document_annotation_format. Setting this prices the call at the annotation rate."
    },
    "table_format": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "markdown",
            "html"
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "Output format for extracted tables"
    },
    "extract_header": {
      "type": "boolean",
      "description": "Extract page headers separately"
    },
    "extract_footer": {
      "type": "boolean",
      "description": "Extract page footers separately"
    },
    "confidence_scores_granularity": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "word",
            "page"
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "Granularity for OCR confidence scores: \"word\" (per-word) or \"page\" (aggregate only). Omit for no confidence scores."
    },
    "document": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "const": "document_url"
            },
            "document_url": {
              "type": "string",
              "format": "uri",
              "description": "Publicly reachable URL of a PDF, PPTX, or DOCX document"
            },
            "document_name": {
              "type": "string",
              "description": "Optional display name for the document"
            }
          },
          "required": [
            "type",
            "document_url"
          ],
          "additionalProperties": false
        },
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "const": "image_url"
            },
            "image_url": {
              "type": "string",
              "format": "uri",
              "description": "Publicly reachable URL of a PNG, JPEG, or AVIF image"
            }
          },
          "required": [
            "type",
            "image_url"
          ],
          "additionalProperties": false
        }
      ],
      "description": "The document or image to process"
    },
    "pages": {
      "anyOf": [
        {
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "integer",
                "minimum": 0
              },
              "maxItems": 1000
            },
            {
              "type": "string",
              "pattern": "^\\d+(-\\d+)?(,\\d+(-\\d+)?)*$"
            }
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "0-indexed pages to process: an array like [0, 1, 2] or a range string like \"0,2-4\", same grammar as upstream (max 1000 distinct pages per call). Each distinct page adds to the price. Omit (or send null or []) to process the whole document: the service then counts the PDF pages itself and prices the full document. PPTX and DOCX inputs must pass explicit pages since their page count depends on rendering. Ignored for image inputs, which always count as one page. Requesting pages beyond the end of the document may fail upstream, in which case the charge is refunded automatically."
    }
  },
  "required": [
    "document"
  ],
  "additionalProperties": false
}
```

**Output Schema**

```json
{
  "type": "object",
  "properties": {
    "pages": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer"
          },
          "markdown": {
            "type": "string"
          },
          "images": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                }
              },
              "required": [
                "id"
              ],
              "additionalProperties": true
            }
          },
          "dimensions": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "dpi": {
                    "type": "number"
                  },
                  "height": {
                    "type": "number"
                  },
                  "width": {
                    "type": "number"
                  }
                },
                "required": [
                  "dpi",
                  "height",
                  "width"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "index",
          "markdown"
        ],
        "additionalProperties": true
      }
    },
    "model": {
      "type": "string"
    },
    "document_annotation": {
      "type": [
        "string",
        "null"
      ]
    },
    "usage_info": {
      "type": "object",
      "properties": {
        "pages_processed": {
          "type": "integer"
        },
        "doc_size_bytes": {
          "type": [
            "number",
            "null"
          ]
        }
      },
      "required": [
        "pages_processed"
      ],
      "additionalProperties": true
    }
  },
  "required": [
    "pages",
    "model",
    "usage_info"
  ],
  "additionalProperties": true
}
```

## How to invoke

Payment is handled automatically — the client signs the 402 challenge and retries.

### TypeScript — Tempo (mppx + fetch) ([docs](https://mpp.dev/sdk/typescript/client))

```ts
import { privateKeyToAccount } from 'viem/accounts'
import { Mppx, tempo } from 'mppx/client'

Mppx.create({
  methods: [tempo({ account: privateKeyToAccount('0x...') })],
})

const res = await fetch('https://mistral.payweave.services/ocr', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "document": {
      "type": "",
      "document_url": "https://example.com",
      "document_name": ""
    },
    "model": "",
    "include_image_base64": false
  }),
})
const data = await res.json()
```

### TypeScript — Solana (@solana/mpp + fetch) ([docs](https://github.com/solana-foundation/mpp-sdk))

```ts
import { createKeyPairSignerFromBytes } from '@solana/kit'
import { Mppx } from 'mppx/client'
import { solana } from '@solana/mpp/client'

const signer = await createKeyPairSignerFromBytes(/* 64-byte secret key */)
Mppx.create({ methods: [solana({ signer })] })

const res = await fetch('https://mistral.payweave.services/ocr', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "document": {
      "type": "",
      "document_url": "https://example.com",
      "document_name": ""
    },
    "model": "",
    "include_image_base64": false
  }),
})
const data = await res.json()
```

### mppx CLI ([docs](https://mpp.dev/sdk/typescript/cli))

```sh
npx mppx "https://mistral.payweave.services/ocr" -X POST -H 'Content-Type: application/json' -d '{"document":{"type":"","document_url":"https://example.com","document_name":""},"model":"","include_image_base64":false}'
```

### Tempo Wallet ([docs](https://docs.tempo.xyz/cli/wallet))

```sh
tempo request "https://mistral.payweave.services/ocr" -X POST --json '{"document":{"type":"","document_url":"https://example.com","document_name":""},"model":"","include_image_base64":false}'
```

### pay.sh — Solana Foundation ([docs](https://pay.sh))

```sh
pay --mainnet curl "https://mistral.payweave.services/ocr" -X POST -H 'Content-Type: application/json' -d '{"document":{"type":"","document_url":"https://example.com","document_name":""},"model":"","include_image_base64":false}'
```

### Mistral: OCR Image

Run Mistral OCR on a single image (PNG, JPEG, or AVIF) by URL and get the text back as markdown. $0.01 flat, or $0.02 when any annotation option is set. Works on photos of receipts, tickets, signs, screenshots, and scanned pages. Same engine as POST /ocr (which also handles PDFs and mirrors api.mistral.ai/v1/ocr); use POST /ocr/upload to send a local image file instead of a URL. The body is validated before charging and upstream failures are refunded automatically.

- Method: POST
- Path: `/ocr/image`
- Price: $0.01000000

**Input Schema**

```json
{
  "type": "object",
  "properties": {
    "image_url": {
      "type": "string",
      "format": "uri",
      "description": "Publicly reachable URL of a PNG, JPEG, or AVIF image, or a data: URI"
    },
    "model": {
      "type": [
        "string",
        "null"
      ],
      "description": "Mistral OCR model id. Defaults to mistral-ocr-latest."
    },
    "include_image_base64": {
      "type": [
        "boolean",
        "null"
      ],
      "description": "Return base64 image data for images extracted from the document"
    },
    "image_limit": {
      "anyOf": [
        {
          "type": "integer",
          "exclusiveMinimum": 0
        },
        {
          "type": "null"
        }
      ],
      "description": "Maximum number of images to extract"
    },
    "image_min_size": {
      "anyOf": [
        {
          "type": "integer",
          "exclusiveMinimum": 0
        },
        {
          "type": "null"
        }
      ],
      "description": "Minimum height and width, in pixels, for an image to be extracted"
    },
    "bbox_annotation_format": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "enum": [
                "text",
                "json_object",
                "json_schema"
              ]
            }
          },
          "required": [
            "type"
          ],
          "additionalProperties": true
        },
        {
          "type": "null"
        }
      ],
      "description": "Structured format for per-image bbox annotations (upstream accepts json_schema only). Setting this prices the call at the annotation rate."
    },
    "document_annotation_format": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string",
              "enum": [
                "text",
                "json_object",
                "json_schema"
              ]
            }
          },
          "required": [
            "type"
          ],
          "additionalProperties": true
        },
        {
          "type": "null"
        }
      ],
      "description": "Structured format for a whole-document annotation (upstream accepts json_schema only). Setting this prices the call at the annotation rate."
    },
    "document_annotation_prompt": {
      "type": [
        "string",
        "null"
      ],
      "description": "Optional prompt guiding structured extraction over the whole document. Requires document_annotation_format. Setting this prices the call at the annotation rate."
    },
    "table_format": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "markdown",
            "html"
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "Output format for extracted tables"
    },
    "extract_header": {
      "type": "boolean",
      "description": "Extract page headers separately"
    },
    "extract_footer": {
      "type": "boolean",
      "description": "Extract page footers separately"
    },
    "confidence_scores_granularity": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "word",
            "page"
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "Granularity for OCR confidence scores: \"word\" (per-word) or \"page\" (aggregate only). Omit for no confidence scores."
    }
  },
  "required": [
    "image_url"
  ],
  "additionalProperties": false
}
```

**Output Schema**

```json
{
  "type": "object",
  "properties": {
    "pages": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer"
          },
          "markdown": {
            "type": "string"
          },
          "images": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                }
              },
              "required": [
                "id"
              ],
              "additionalProperties": true
            }
          },
          "dimensions": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "dpi": {
                    "type": "number"
                  },
                  "height": {
                    "type": "number"
                  },
                  "width": {
                    "type": "number"
                  }
                },
                "required": [
                  "dpi",
                  "height",
                  "width"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "index",
          "markdown"
        ],
        "additionalProperties": true
      }
    },
    "model": {
      "type": "string"
    },
    "document_annotation": {
      "type": [
        "string",
        "null"
      ]
    },
    "usage_info": {
      "type": "object",
      "properties": {
        "pages_processed": {
          "type": "integer"
        },
        "doc_size_bytes": {
          "type": [
            "number",
            "null"
          ]
        }
      },
      "required": [
        "pages_processed"
      ],
      "additionalProperties": true
    }
  },
  "required": [
    "pages",
    "model",
    "usage_info"
  ],
  "additionalProperties": true
}
```

## How to invoke

Payment is handled automatically — the client signs the 402 challenge and retries.

### TypeScript — Tempo (mppx + fetch) ([docs](https://mpp.dev/sdk/typescript/client))

```ts
import { privateKeyToAccount } from 'viem/accounts'
import { Mppx, tempo } from 'mppx/client'

Mppx.create({
  methods: [tempo({ account: privateKeyToAccount('0x...') })],
})

const res = await fetch('https://mistral.payweave.services/ocr/image', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "image_url": "https://example.com",
    "model": "",
    "include_image_base64": false
  }),
})
const data = await res.json()
```

### TypeScript — Solana (@solana/mpp + fetch) ([docs](https://github.com/solana-foundation/mpp-sdk))

```ts
import { createKeyPairSignerFromBytes } from '@solana/kit'
import { Mppx } from 'mppx/client'
import { solana } from '@solana/mpp/client'

const signer = await createKeyPairSignerFromBytes(/* 64-byte secret key */)
Mppx.create({ methods: [solana({ signer })] })

const res = await fetch('https://mistral.payweave.services/ocr/image', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "image_url": "https://example.com",
    "model": "",
    "include_image_base64": false
  }),
})
const data = await res.json()
```

### mppx CLI ([docs](https://mpp.dev/sdk/typescript/cli))

```sh
npx mppx "https://mistral.payweave.services/ocr/image" -X POST -H 'Content-Type: application/json' -d '{"image_url":"https://example.com","model":"","include_image_base64":false}'
```

### Tempo Wallet ([docs](https://docs.tempo.xyz/cli/wallet))

```sh
tempo request "https://mistral.payweave.services/ocr/image" -X POST --json '{"image_url":"https://example.com","model":"","include_image_base64":false}'
```

### pay.sh — Solana Foundation ([docs](https://pay.sh))

```sh
pay --mainnet curl "https://mistral.payweave.services/ocr/image" -X POST -H 'Content-Type: application/json' -d '{"image_url":"https://example.com","model":"","include_image_base64":false}'
```

### Mistral: OCR Upload

Upload a file directly via multipart/form-data and run Mistral OCR on it — no hosting step needed. Same pricing as POST /ocr: $0.01 per page, $0.02 per page with annotation options. Fields: file (PDF or PNG/JPEG/AVIF image, max 50 MB), pages (optional, a range string like "0,2-4" or JSON array string like "[0,1]"; omit to process the whole PDF, counted from the uploaded bytes, max 25 MB for whole-document pricing), and options (optional JSON object string with the same option fields as POST /ocr). Images always count as one page. The body is validated before charging and upstream failures are refunded automatically.

- Method: POST
- Path: `/ocr/upload`
- Price: $0.01000000
- Content-Type: multipart/form-data

**Input Schema**

```json
{
  "type": "object",
  "properties": {
    "file": {
      "description": "The document (PDF) or image (PNG, JPEG, AVIF) to process"
    },
    "pages": {
      "anyOf": [
        {
          "anyOf": [
            {
              "type": "array",
              "items": {
                "type": "integer",
                "minimum": 0
              },
              "maxItems": 1000
            },
            {
              "type": "string",
              "pattern": "^\\d+(-\\d+)?(,\\d+(-\\d+)?)*$"
            }
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "Same semantics as POST /ocr pages, as a form field: a range string like \"0,2-4\" or a JSON array string like \"[0, 1, 2]\". Omit to process the whole document (PDF page count is determined from the uploaded bytes; images always count as one page)."
    },
    "options": {
      "type": "object",
      "properties": {
        "model": {
          "type": [
            "string",
            "null"
          ],
          "description": "Mistral OCR model id. Defaults to mistral-ocr-latest."
        },
        "include_image_base64": {
          "type": [
            "boolean",
            "null"
          ],
          "description": "Return base64 image data for images extracted from the document"
        },
        "image_limit": {
          "anyOf": [
            {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            {
              "type": "null"
            }
          ],
          "description": "Maximum number of images to extract"
        },
        "image_min_size": {
          "anyOf": [
            {
              "type": "integer",
              "exclusiveMinimum": 0
            },
            {
              "type": "null"
            }
          ],
          "description": "Minimum height and width, in pixels, for an image to be extracted"
        },
        "bbox_annotation_format": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "text",
                    "json_object",
                    "json_schema"
                  ]
                }
              },
              "required": [
                "type"
              ],
              "additionalProperties": true
            },
            {
              "type": "null"
            }
          ],
          "description": "Structured format for per-image bbox annotations (upstream accepts json_schema only). Setting this prices the call at the annotation rate."
        },
        "document_annotation_format": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "text",
                    "json_object",
                    "json_schema"
                  ]
                }
              },
              "required": [
                "type"
              ],
              "additionalProperties": true
            },
            {
              "type": "null"
            }
          ],
          "description": "Structured format for a whole-document annotation (upstream accepts json_schema only). Setting this prices the call at the annotation rate."
        },
        "document_annotation_prompt": {
          "type": [
            "string",
            "null"
          ],
          "description": "Optional prompt guiding structured extraction over the whole document. Requires document_annotation_format. Setting this prices the call at the annotation rate."
        },
        "table_format": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "markdown",
                "html"
              ]
            },
            {
              "type": "null"
            }
          ],
          "description": "Output format for extracted tables"
        },
        "extract_header": {
          "type": "boolean",
          "description": "Extract page headers separately"
        },
        "extract_footer": {
          "type": "boolean",
          "description": "Extract page footers separately"
        },
        "confidence_scores_granularity": {
          "anyOf": [
            {
              "type": "string",
              "enum": [
                "word",
                "page"
              ]
            },
            {
              "type": "null"
            }
          ],
          "description": "Granularity for OCR confidence scores: \"word\" (per-word) or \"page\" (aggregate only). Omit for no confidence scores."
        }
      },
      "additionalProperties": false,
      "description": "Optional JSON object string with the same option fields as POST /ocr (model, include_image_base64, image_limit, image_min_size, bbox_annotation_format, document_annotation_format, document_annotation_prompt, table_format, extract_header, extract_footer, confidence_scores_granularity). Annotation options price the call at the annotation rate."
    }
  },
  "required": [
    "file"
  ],
  "additionalProperties": false
}
```

**Output Schema**

```json
{
  "type": "object",
  "properties": {
    "pages": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer"
          },
          "markdown": {
            "type": "string"
          },
          "images": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                }
              },
              "required": [
                "id"
              ],
              "additionalProperties": true
            }
          },
          "dimensions": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "dpi": {
                    "type": "number"
                  },
                  "height": {
                    "type": "number"
                  },
                  "width": {
                    "type": "number"
                  }
                },
                "required": [
                  "dpi",
                  "height",
                  "width"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "index",
          "markdown"
        ],
        "additionalProperties": true
      }
    },
    "model": {
      "type": "string"
    },
    "document_annotation": {
      "type": [
        "string",
        "null"
      ]
    },
    "usage_info": {
      "type": "object",
      "properties": {
        "pages_processed": {
          "type": "integer"
        },
        "doc_size_bytes": {
          "type": [
            "number",
            "null"
          ]
        }
      },
      "required": [
        "pages_processed"
      ],
      "additionalProperties": true
    }
  },
  "required": [
    "pages",
    "model",
    "usage_info"
  ],
  "additionalProperties": true
}
```

## How to invoke

Payment is handled automatically — the client signs the 402 challenge and retries.

### TypeScript — Tempo (mppx + fetch) ([docs](https://mpp.dev/sdk/typescript/client))

```ts
import { privateKeyToAccount } from 'viem/accounts'
import { Mppx, tempo } from 'mppx/client'

Mppx.create({
  methods: [tempo({ account: privateKeyToAccount('0x...') })],
})

const form = new FormData()
form.append('file', /* File from <input> or Blob */, 'file.bin')
form.append('pages', '[0]')
form.append('options', '{"model":"","include_image_base64":false,"image_limit":0}')

const res = await fetch('https://mistral.payweave.services/ocr/upload', {
  method: 'POST',
  body: form,
})
const data = await res.json()
```

### TypeScript — Solana (@solana/mpp + fetch) ([docs](https://github.com/solana-foundation/mpp-sdk))

```ts
import { createKeyPairSignerFromBytes } from '@solana/kit'
import { Mppx } from 'mppx/client'
import { solana } from '@solana/mpp/client'

const signer = await createKeyPairSignerFromBytes(/* 64-byte secret key */)
Mppx.create({ methods: [solana({ signer })] })

const form = new FormData()
form.append('file', /* File from <input> or Blob */, 'file.bin')
form.append('pages', '[0]')
form.append('options', '{"model":"","include_image_base64":false,"image_limit":0}')

const res = await fetch('https://mistral.payweave.services/ocr/upload', {
  method: 'POST',
  body: form,
})
const data = await res.json()
```

### mppx CLI ([docs](https://mpp.dev/sdk/typescript/cli))

```sh
npx mppx "https://mistral.payweave.services/ocr/upload" -X POST -F "file=@./file.bin" -F "pages=[0]" -F "options={"model":"","include_image_base64":false,"image_limit":0}"
```

### Tempo Wallet ([docs](https://docs.tempo.xyz/cli/wallet))

```sh
tempo request "https://mistral.payweave.services/ocr/upload" -X POST -F "file=@./file.bin" -F "pages=[0]" -F "options={"model":"","include_image_base64":false,"image_limit":0}"
```

### pay.sh — Solana Foundation ([docs](https://pay.sh))

```sh
pay --mainnet curl "https://mistral.payweave.services/ocr/upload" -X POST -F "file=@./file.bin" -F "pages=[0]" -F "options={"model":"","include_image_base64":false,"image_limit":0}"
```
