---
title: "Download a quote as PDF"
method: GET
path: "/quotes/{id}/pdf"
tags: ["Quotes"]
---

# Download a quote as PDF

`GET /quotes/{id}/pdf`

## Request

- Base URL: `https://joinways.app/api/v1`
- URL: `https://joinways.app/api/v1/quotes/{id}/pdf`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://joinways.app/oauth/authorize`, token URL `https://joinways.app/api/oauth/token`, scopes: `mcp.read`)

Renders the quote like the app's download (never issues an invoice, never stores a version). A platform quote returns the platform's own PDF instead (`locale` ignored), or `409` when none is stored yet. **Role permission:** `reports.view` or `quotes.manage`.

## Query parameters

- `locale` 'fr' | 'en' | 'es'

## Response `200`

PDF document (`Content-Disposition` attachment).

## Other responses

- `401`: Missing, invalid, expired or revoked bearer token (`unauthorized`).
- `403`: `forbidden`: the token lacks the scope, its owner's role lacks the permission named by the operation, or the workspace has neither the Pro plan nor a trial (`details.reason` `plan_not_eligible`).
- `404`: Not found in this workspace, or the id of the path is not a UUID (`not_found`).
- `409`: The state of the record refuses the operation (`conflict`). `details.reason` is a stable code.
- `429`: Too many requests (`rate_limited`). `details.reason`: `per-ip`, `per-account-minute`, `per-account-day`, or `email_rate_limited` (email budget). Always carries `Retry-After`: wait that many seconds.

---

[API](https://skmtc.dev/joinways/apis/joinways-public-api.md) · [All operations](https://skmtc.dev/joinways/apis/joinways-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/joinways/apis/joinways-public-api/revisions/39e84309953e?raw)
