Appearance
Events & due periods
A patent event is one dated obligation on a patent. Today the only kind is a renewal: one annuity (maintenance fee) falling due. Events are the resource you will read most often. They carry the deadline, the urgency classification, the fee summary, the processing progress, and the instructability affordance that tells you whether you can act on them right now.
This page walks through the event object itself. For the surrounding process (how events are generated, instructed, paid, and invoiced), see Lifecycle of a renewal and the monthly renewal cycle guide.
Anatomy of a patent event
Every event endpoint returns the same shape. Fields are always present unless marked otherwise; nullable fields are emitted as null, never omitted.
| Field | Type | Description |
|---|---|---|
object | string | Always "patentEvent". |
id | string (UUID) | Opaque, stable Renewr UUID of the event. Use it in URL paths and in instruction payloads. |
patent | object | The patent this event belongs to, identified both ways. |
patent.id | string (UUID) | Renewr UUID of the patent. |
patent.providerId | string, nullable | Your own matching reference for that patent; it lets you reconcile events without an extra lookup. |
eventType | string enum, open | Business kind of the event. RENEWAL is the only kind today; new kinds will be added over time. See below. |
dueDate | string, YYYY-MM-DD | The date the fee must be paid by. |
gracePeriodEndDate | string YYYY-MM-DD, nullable | End of the office's grace period. See Grace period. |
renewal | object, nullable | Renewal-specific identification, non-null exactly when eventType is RENEWAL (today: every event). |
renewal.annuityYear | integer | Which year of the patent's life this fee pays for (e.g. year 5 of 20). |
renewal.paymentSequenceNumber | integer, nullable | The office's payment sequence number, present only when it differs from annuityYear (offices with irregular payment cadences). null means "same as annuityYear". |
appliedDecision | enum PROCEED | SKIP_THIS_TIME | DROP, nullable | The instruction that has been applied to this event; null while no instruction has been executed. See Instructions & instructability. |
duePeriod | enum UPCOMING | CURRENT | LATE | GRACE_PERIOD | LAPSED, nullable | Where the event sits relative to its deadline. See below. |
processingStatus | enum, nullable | How far Renewr has taken the event through its pipeline. See below. |
processingStatusUpdatedAt | string ISO 8601, nullable | Timestamp of the last processingStatus change. |
isFxRateFrozen | boolean | true when the FX rate used to compute this event's fees is frozen. See Fees & FX. |
feesStatus | enum ESTIMATED | INVOICED, nullable | Whether the fees for this event are projected (ESTIMATED) or final (INVOICED, meaning an invoice exists). |
createdAt | string ISO 8601, nullable | Creation timestamp. |
updatedAt | string ISO 8601, nullable | Last update timestamp. |
instructability | object | Whether and how this event can be instructed right now. Present on every event endpoint. Covered in depth in Instructions & instructability. |
fees | object, optional | Estimated fee breakdown, present only when requested with include=fees on GET /patent-events; omitted (not null) otherwise. Shape documented in Fees & FX. |
A full event, as returned by GET /api/v2/external/patents/{patentId}/events/{eventId}:
json
{
"object": "patentEvent",
"id": "7f3d2a1e-8c4b-4f6a-9e2d-5b1c8a7f4e3d",
"patent": {
"id": "b2e5c9d4-1a7f-4e8b-a3c6-9f0d2e5b8a1c",
"providerId": "ACME-EP-0042"
},
"eventType": "RENEWAL",
"dueDate": "2026-09-30",
"gracePeriodEndDate": "2027-03-31",
"renewal": {
"annuityYear": 5,
"paymentSequenceNumber": null
},
"appliedDecision": null,
"duePeriod": "UPCOMING",
"processingStatus": "NOT_INSTRUCTED",
"processingStatusUpdatedAt": null,
"isFxRateFrozen": false,
"feesStatus": "ESTIMATED",
"createdAt": "2026-01-12T08:24:31.000Z",
"updatedAt": "2026-07-01T02:10:05.000Z",
"instructability": {
"isAllowed": true,
"allowedDecisions": ["PROCEED", "SKIP_THIS_TIME", "DROP"],
"blockedReason": null,
"opensAt": "2026-07-01",
"mode": "DIRECT"
}
}Note the combination in this example: duePeriod is still UPCOMING, yet instructability.isAllowed is true because the instruction window opened on opensAt. This is normal; see the warning below.
Dates and timestamps
Calendar dates (dueDate, gracePeriodEndDate, opensAt) are YYYY-MM-DD strings. Timestamps (createdAt, updatedAt, processingStatusUpdatedAt) are full ISO 8601 UTC strings. See Conventions.
eventType is an open enum
RENEWAL is the only event kind today, but the enum is open by contract: Renewr will add new kinds over time without a version bump. Write your integration so that it ignores events whose eventType it does not recognize rather than failing on them.
Two related guarantees:
- The
renewalsub-object is non-null exactly wheneventTypeis"RENEWAL". Future event kinds will carry their own type-specific sub-object and anullrenewal. - On the cross-portfolio list, you can pin your integration to renewals ahead of future kinds by passing
eventTypes=RENEWALtoGET /patent-events.
duePeriod: the urgency buckets
duePeriod classifies each event relative to its dueDate and gracePeriodEndDate. Think of it as an urgency bucket, recomputed live. If you are new to patent renewals, this table is the mental model:
| Value | Meaning | What to do |
|---|---|---|
UPCOMING | Due later, beyond the current instruction cycle. | Nothing required yet. It may already be instructable; instructability is the field to check for that, since duePeriod does not carry this information. |
CURRENT | Due within the normal instruction cycle (roughly one to two months out). | Instruct now. This is the bucket a monthly cycle works through. |
LATE | Due imminently. | Instruct urgently; the payment must go out. |
GRACE_PERIOD | The due date has passed but gracePeriodEndDate has not: the office still accepts payment, with a surcharge. | Still recoverable, so decide fast. The surcharge appears as the GRACE_PERIOD fee component (see Fees & FX). |
LAPSED | Past gracePeriodEndDate: the office no longer accepts payment; the patent right is lost (barring exceptional revival). | PROCEED is no longer offered: instructability.allowedDecisions shrinks to SKIP_THIS_TIME and DROP. |
The grace period
Most offices grant a statutory extra window after the due date during which they still accept the annuity payment, in exchange for a late surcharge. That window ends at gracePeriodEndDate. While an event is in it (duePeriod: "GRACE_PERIOD"), a PROCEED instruction is still possible and the estimated fees include the surcharge as a dedicated GRACE_PERIOD component.
Once gracePeriodEndDate passes, the event becomes LAPSED and the right is normally lost. POSTing PROCEED on a lapsed event is rejected with 422 instruction_lapsed: the decision is simply no longer offered (see the error catalog). You can still record SKIP_THIS_TIME (someone else handled it) or DROP (abandon).
duePeriod is informative; instructability is authoritative
duePeriod tells you how urgent an event is; it does not tell you whether you can act. The instruction window is calendar-anchored (it opens on instructability.opensAt, the first day of the month two months before the due month), so an event whose duePeriod still reads UPCOMING can already be instructable. The exact bucket boundaries are an implementation detail and may shift, so never derive "can I instruct?" from duePeriod. Use instructability.isAllowed and allowedDecisions, which are computed from the same rules the instruction endpoint enforces.
processingStatus: Renewr's execution pipeline
While duePeriod looks at the calendar, processingStatus looks at work done: how far Renewr has taken the event through instruction, payment, and proof. It is persisted (it is never recomputed on read), and every change updates processingStatusUpdatedAt.
| Status | Operational meaning |
|---|---|
NOT_INSTRUCTED | Default at event creation. Renewr is waiting for your decision. |
INSTRUCTED | Your instruction was executed, set synchronously during the POST. |
PAYMENT_SENT | Renewr included the fee in a payment batch sent to the office or local agent. |
PAYMENT_CONFIRMED | The payment was confirmed received. |
FULFILLED | Terminal, happy. The office's official receipt was recorded with no problem: the annuity is proven paid. The receipt PDF is downloadable via GET .../documents/official-receipt (see Downloading documents). |
UNPROCESSABLE | Terminal, problem. The official-receipt stage recorded a renewal problem (office rejection or complication). Renewr operators handle it, so contact Renewr support about this event. |
For a SKIP_THIS_TIME or DROP decision there is no payment to make, so such events do not progress through the payment stages. Migrating from v1? The v1 status vocabulary maps onto these six states non-trivially; see the v1 to v2 migration guide.
Where events appear
Events surface on five read endpoints, in two shapes:
| Endpoint | Response shape | Use for |
|---|---|---|
GET /api/v2/external/patents/{patentId}/events | Bare JSON array (no envelope, no pagination) | All events of one patent. |
GET /api/v2/external/patents/{patentId}/events/{eventId} | Single object | One event in full. |
GET /api/v2/external/patents/{patentId}/events/{eventId}/fees | Single fees object | The fee breakdown for one event (Fees & FX). |
GET /api/v2/external/patent-events | List envelope { pagination, data } | Cross-portfolio: everything falling due in a window. |
GET .../events/{eventId}/documents/* | PDF binary | Per-event documents (guide). |
Every event returned by the first two and the period list carries instructability.
The per-patent list is a bare array
GET /patents/{patentId}/events returns a plain JSON array ([ { "object": "patentEvent", ... } ]). The { pagination, data } envelope used by other lists does not apply here. A patent has a bounded set of events, so it is returned whole. Parse accordingly.
Per patent: the event schedule
Use the per-patent list when you are looking at one case: it returns the patent's full renewal schedule, past and future:
bash
curl "https://api.renewr.example/api/v2/external/patents/b2e5c9d4-1a7f-4e8b-a3c6-9f0d2e5b8a1c/events" \
-H "x-api-key: $RENEWR_API_KEY"Cross-portfolio: what falls due in a window
GET /patent-events is the workhorse of a monthly integration cycle: one call answers "what falls due across my whole portfolio in this window?". A due window is required: pass either dueMonth=YYYY-MM or both dueFrom and dueTo (YYYY-MM-DD, inclusive); omitting both yields a 400 validation_failed. Optional filters: offices, owners, family, eventTypes (all repeatable), plus include=fees to embed each event's estimated fee breakdown:
bash
curl "https://api.renewr.example/api/v2/external/patent-events?dueMonth=2026-09&offices=EP&include=fees" \
-H "x-api-key: $RENEWR_API_KEY"The response uses the standard list envelope (itemsPerPage default 10, capped at 100; see Conventions):
json
{
"pagination": {
"totalItems": 42,
"currentPage": 1,
"itemsPerPage": 10,
"totalPages": 5,
"hasMore": true
},
"data": [ { "object": "patentEvent", "...": "..." } ]
}Unknown include values are silently ignored. Note that the window filters on the events' dueDate, and estimated fees are computed live; see Syncing data for what you can and cannot cache.