Appearance
Downloading documents
Every patent event exposes up to three PDF documents, each one produced at a different stage of the renewal lifecycle. All three live under the event resource and are downloaded the same way. The only difference is when they come into existence.
All three endpoints require the patents:read scope and authenticate with your API key like every other call. See Authentication.
The three documents
| Document | Endpoint | What it is |
|---|---|---|
| Invoice | GET /patents/{patentId}/events/{eventId}/documents/invoice | The invoice document covering this event's fees. |
| Instruction receipt | GET /patents/{patentId}/events/{eventId}/documents/instruction-receipt | Your proof of order: the receipt generated when your instruction was executed. |
| Official receipt | GET /patents/{patentId}/events/{eventId}/documents/official-receipt | The patent office's proof that the annuity was actually paid. |
The final path segment is a fixed name (invoice, instruction-receipt, official-receipt). It is never a free-form document identifier.
When each document becomes available
A document endpoint returns 404 not_found until the underlying document exists, then 200 with the PDF from that point on. Each document appears at a specific lifecycle stage, and each stage has an observable signal on the event itself (GET /patents/{patentId}/events/{eventId}):
| Document | Becomes available once… | Signal to watch on the event |
|---|---|---|
| Invoice | …the event has been invoiced. | feesStatus is INVOICED (the fees endpoint then also carries a non-null invoiceId). |
| Instruction receipt | …you have instructed the event via POST /patent-instructions. | appliedDecision is non-null; processingStatus is INSTRUCTED or later. |
| Official receipt | …the office's payment proof has been recorded. | processingStatus is FULFILLED. |
A 404 here is not an error condition
Until the relevant stage is reached, the response is a regular problem+json 404 with code not_found. Treat it as "not yet": retry after the lifecycle signal above flips, rather than alerting on the first 404. A 404 at this stage never indicates a failure. As always with data syncing, poll the event's status fields to decide when a download is worth attempting.
The instruction receipt's metadata (issue date, reference, sequential number) is also returned as JSON in the 201 response of POST /patent-instructions. The PDF endpoint gives you the same receipt as a document you can archive or forward. See Instructions and instructability.
Downloading with curl
The response is the PDF binary streamed with Content-Type: application/pdf and a Content-Disposition: attachment header carrying the filename. With -OJ, curl saves the file under the server-provided name:
bash
curl -fOJ "https://api.renewr.example/api/v2/external/patents/6f9619ff-8b86-4d01-b42d-00cf4fc964ff/events/1c2a4e88-53a1-4467-9d33-7f2b8e0a54c1/documents/invoice" \
-H "x-api-key: $RENEWR_API_KEY"
# saves: invoice-1c2a4e88-53a1-4467-9d33-7f2b8e0a54c1.pdfbash
curl -fOJ "https://api.renewr.example/api/v2/external/patents/6f9619ff-8b86-4d01-b42d-00cf4fc964ff/events/1c2a4e88-53a1-4467-9d33-7f2b8e0a54c1/documents/instruction-receipt" \
-H "x-api-key: $RENEWR_API_KEY"
# saves: instruction-receipt-1c2a4e88-53a1-4467-9d33-7f2b8e0a54c1.pdfbash
curl -fOJ "https://api.renewr.example/api/v2/external/patents/6f9619ff-8b86-4d01-b42d-00cf4fc964ff/events/1c2a4e88-53a1-4467-9d33-7f2b8e0a54c1/documents/official-receipt" \
-H "x-api-key: $RENEWR_API_KEY"
# saves: official-receipt-1c2a4e88-53a1-4467-9d33-7f2b8e0a54c1.pdfUse -f (--fail) with -OJ
On a 404 there is no Content-Disposition header, so a plain curl -OJ would save the JSON error body to disk under the last URL segment (e.g. a file named invoice). -f makes curl exit non-zero instead, which is what you want in a script.
Filenames are deterministic (<document-name>-<eventId>.pdf), so you can also name files yourself and skip -J entirely.
Response format
| Header | Value |
|---|---|
Content-Type | application/pdf |
Content-Disposition | attachment; filename="invoice-<eventId>.pdf"; filename*=UTF-8''invoice-<eventId>.pdf (RFC 6266, with the UTF-8 filename* form) |
Access-Control-Expose-Headers | Content-Disposition |
RateLimit-Limit / RateLimit-Remaining / RateLimit-Reset | Standard rate-limit headers, present as on every authenticated response |
X-Request-Id | Correlation id, present on every response |
Browser clients
Content-Disposition is explicitly listed in Access-Control-Expose-Headers, so a browser-based client fetching the PDF cross-origin can read the header and reuse the server's filename when saving the blob.
The body is streamed directly: there is no JSON envelope, no base64 encoding, and no intermediate "download URL" step.
Errors
| Status | Code | When |
|---|---|---|
400 | validation_failed | patentId or eventId is not a valid UUID (standard problem+json envelope). |
401 | invalid_api_key / api_key_expired | Missing or invalid key / expired key. |
403 | insufficient_scope | Your key lacks the patents:read scope. |
404 | not_found | Unknown patent or event in your tenant, or the document does not exist yet (see above). |
429 | rate_limit_exceeded | Daily quota exhausted; retry after the Retry-After delay. |
See Errors for the full problem+json contract.
Invoice documents at the invoice level
The invoice resource describes whether documents exist for an invoice (hasPdfDocument, hasXlsxDocument); the download itself happens per event. An invoice's fees[] lines each carry an eventId, so from any invoice returned by GET /invoices/{invoiceId} you can resolve the events it covers and download each event's invoice document.
Related pages
- The renewal lifecycle: the stages that produce each document
- Instructions and instructability: how instructing works, and the receipt it produces
- The monthly renewal cycle: where document downloads fit in a monthly integration
- Syncing data: polling patterns for status-driven downloads
- Errors: the problem+json contract behind the 404s