Appearance
Instructions & instructability
An instruction is your decision on one patent event: renew it, skip it this time, or abandon the patent. It is the single write operation of the patent surface. Everything else in the API exists to help you make this decision and to prove what happened after you made it.
This page explains the three decisions, the instructability object that tells you when you can act, the DIRECT execution mode, batching rules, and the instruction receipt you get back.
What an instruction is
You submit instructions with POST /api/v2/external/patent-instructions, one entry per event:
bash
curl -X POST "https://api.renewr.example/api/v2/external/patent-instructions" \
-H "x-api-key: $RENEWR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"instructions": [
{ "eventId": "8a4f2c1e-9b3d-4e7a-a1c5-6d2f8e0b4a91", "decision": "PROCEED" }
]
}'Instructions are write-only by design. There is no GET /patent-instructions, no update, no delete. The flow is: POST your decision, then observe its effects on the resources you already read:
- The 201 response is an instruction receipt, your proof of order.
- The event reflects the outcome:
GET /patents/{patentId}/events/{eventId}showsappliedDecision(the decision you gave) andprocessingStatus(how far Renewr has taken it; see Lifecycle). - The receipt PDF is downloadable at
GET .../events/{eventId}/documents/instruction-receipt. See Downloading documents.
Scope
This endpoint requires the patents:instructions:write scope on your API key. See Authentication.
The three decisions
The decision field takes one of three values:
| Decision | Meaning | Effect on future events |
|---|---|---|
PROCEED | "Pay this annuity." Renewr executes the renewal: payment to the office/agent, invoicing, receipts. | None. The chain continues; the next annuity will come due and be presented for instruction as usual. |
SKIP_THIS_TIME | "Not through Renewr this time." This occurrence is handled elsewhere (by you or another provider); Renewr does not pay. | Future events are kept. The chain continues; the next annuity will be presented normally. |
DROP | "Abandon: never renew this patent again." | Terminal. All remaining un-instructed future events of the patent are deleted, and the right will lapse at the office. |
DROP is irreversible
Executing a DROP immediately deletes every remaining un-instructed future event of the patent. There is no API operation to undo it, and once the office deadline passes the patent right itself lapses, normally beyond recovery. Reserve DROP for a confirmed, final abandonment decision. If the annuity is merely being paid through another channel, use SKIP_THIS_TIME.
Instructability: "can I act on this event right now?"
Every event returned by the API (on GET /patents/{patentId}/events, GET .../events/{eventId}, and the cross-portfolio GET /patent-events) carries an instructability object:
json
{
"isAllowed": true,
"allowedDecisions": ["PROCEED", "SKIP_THIS_TIME", "DROP"],
"blockedReason": null,
"opensAt": "2026-07-01",
"mode": "DIRECT"
}| Field | Type | Description |
|---|---|---|
isAllowed | boolean | Whether an instruction can be POSTed on this event right now. |
allowedDecisions | array | The decisions valid right now. Empty when isAllowed is false; a lapsed event drops PROCEED. |
blockedReason | enum, nullable | Why the event is blocked: ALREADY_INSTRUCTED | TOO_EARLY | EARLIER_EVENT_PENDING. null when allowed. |
opensAt | date, nullable | Calendar date the instruction window opens (YYYY-MM-DD). A past date means the window is already open. |
mode | enum | How an instruction would be processed now. DIRECT is the only value today (open enum). |
The rules, in evaluation order
The server evaluates these rules in order and reports the first one that blocks:
ALREADY_INSTRUCTED: the event already has an executed decision.allowedDecisionsis empty; re-posting yields409 instruction_already_set. Read the outcome on the event'sappliedDecisioninstead.TOO_EARLY: the instruction window has not opened yet. The window opens onopensAt= the first day of the month two months before the due month. Concretely: an event withdueDate: "2026-09-30"becomes instructable onopensAt: "2026-07-01".EARLIER_EVENT_PENDING(the order rule): only the chronologically earliest un-instructed event of a patent can be instructed. If an earlier event of the same patent is still waiting for a decision, this one is blocked; instruct that one first. Already-instructed earlier events don't block anything.Allowed, but lapsed: no
PROCEED. When an event'sduePeriodisLAPSED(the grace period is over),isAllowedstaystruebutallowedDecisionsshrinks to["SKIP_THIS_TIME", "DROP"]: the office no longer accepts payment, so "renew it" is not offered. You can still record that the annuity was handled elsewhere, or abandon.
The window is calendar-anchored, so trust instructability over duePeriod
opensAt is derived from the due date. The event's duePeriod bucket plays no part in the calculation. An event whose duePeriod still reads UPCOMING can already be instructable. Always use instructability.isAllowed and opensAt to decide when to act; treat duePeriod as informative context.
A blocked event looks like this:
json
{
"isAllowed": false,
"allowedDecisions": [],
"blockedReason": "TOO_EARLY",
"opensAt": "2026-10-01",
"mode": "DIRECT"
}The golden rule
Never send a decision that is not in allowedDecisions. The POST validator applies exactly the same rules that compute instructability (one rule, two consumers), so what you see on the read side is precisely what will be enforced on the write side. Each violation maps 1:1 to a stable error code:
| You violated | Read-side signal | Error on POST |
|---|---|---|
| Event already instructed | blockedReason: "ALREADY_INSTRUCTED" | 409 instruction_already_set |
| Window not open yet | blockedReason: "TOO_EARLY" | 422 instruction_too_early |
| An earlier event is pending | blockedReason: "EARLIER_EVENT_PENDING" | 422 instruction_skipped |
Decision not offered (e.g. PROCEED on a lapsed event) | decision missing from allowedDecisions | 422 instruction_lapsed |
All errors use the application/problem+json envelope with these stable code values. See Errors for the full catalog and envelope shape.
Execution mode: DIRECT
mode: "DIRECT" is the only mode on the external API today. A direct instruction is executed immediately and synchronously inside the POST: by the time you receive the 201, the decision has been applied to the event, the instruction receipt has been issued, and the corresponding invoice line has been created. There is no pending state to poll for the instruction itself. Subsequent payment progress is tracked on the event's processingStatus (see Lifecycle).
The flip side: a direct instruction is not modifiable via the API afterwards. There is no endpoint to amend or cancel it. If you believe an instruction was submitted in error, contact Renewr support.
mode is an open enum
A SCHEDULED mode (instructions registered ahead of time) may appear in a future version. Treat mode as an open enum and tolerate values you don't recognize. See Conventions.
Batching instructions
The instructions array accepts multiple entries, so one call can instruct events across many patents:
bash
curl -X POST "https://api.renewr.example/api/v2/external/patent-instructions" \
-H "x-api-key: $RENEWR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"instructions": [
{ "eventId": "8a4f2c1e-9b3d-4e7a-a1c5-6d2f8e0b4a91", "decision": "PROCEED" },
{ "eventId": "c1d0e9f8-7a6b-4c5d-8e2f-3a4b5c6d7e8f", "decision": "PROCEED" },
{ "eventId": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9", "decision": "SKIP_THIS_TIME" }
]
}'Two rules govern batches:
- Many patents per call, but only one event per patent. This follows directly from the order rule: only the earliest un-instructed event of each patent is actionable, so a second event of the same patent in the same batch is validated against pre-execution state and fails with
422 instruction_skipped. Instruct the next event of that patent in a later call. - All-or-nothing. If any entry fails validation, the entire batch rolls back; there is no partial execution. The error response identifies the offending entry (validation failures carry RFC 6901 JSON Pointers such as
/instructions/2/eventId; see Errors).
Batch defensively
Build batches only from events whose instructability.isAllowed is true and whose decision is in allowedDecisions at the time you POST. Because a single bad entry rolls back the whole batch, pre-filtering against instructability is the difference between one clean call and a retry loop. The monthly renewal cycle guide shows this end to end.
The instruction receipt
A successful POST returns 201 Created with an instruction receipt, the durable proof of your order:
json
{
"object": "instructionReceipt",
"issueDate": "2026-07-22",
"reference": "REC-2026-0142",
"number": 142,
"instructions": [
{
"object": "instruction",
"id": "f3b8d6a2-1c4e-4f9a-b7d0-5e8c2a9f6b31",
"decision": "PROCEED",
"status": "EXECUTED",
"executedAt": "2026-07-22T09:14:03.512Z",
"scheduledForExecutionAt": null,
"renewedDesignatedCountries": null,
"excludedDesignatedCountries": null
}
]
}| Field | Type | Description |
|---|---|---|
object | "instructionReceipt" | Object type discriminator. |
issueDate | date, nullable | Date the receipt was issued (YYYY-MM-DD). |
reference | string, nullable | Stable display reference of the receipt. |
number | integer, nullable | Sequential receipt number. |
instructions | array | One entry per instruction carried by this receipt. |
Each entry in instructions[]:
| Field | Type | Description |
|---|---|---|
object | "instruction" | Object type discriminator. |
id | UUID | Opaque Renewr UUID of the instruction. |
decision | enum, nullable | PROCEED | SKIP_THIS_TIME | DROP. |
status | enum | Lifecycle status: PENDING | SCHEDULED | EXECUTED | SUPERSEDED. With mode DIRECT, instructions come back EXECUTED on the 201. |
executedAt | timestamp, nullable | When the instruction was executed (ISO 8601 UTC). |
scheduledForExecutionAt | date, nullable | When the instruction is scheduled to execute; null for DIRECT instructions. |
renewedDesignatedCountries | array, nullable | Always null for patent instructions (reserved field). |
excludedDesignatedCountries | array, nullable | Always null for patent instructions (reserved field). |
The PDF version of the receipt is available per event at GET /patents/{patentId}/events/{eventId}/documents/instruction-receipt. Later in the pipeline, the same document family gives you the per-event invoice (.../documents/invoice) and, once the office confirms payment, the official receipt (.../documents/official-receipt). See Downloading documents.
After a PROCEED, the billed amounts appear on the event's fees (GET .../events/{eventId}/fees) once invoiced. See Fees & FX for how estimates become invoiced amounts.