Skip to content

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.

FieldTypeDescription
objectstringAlways "patentEvent".
idstring (UUID)Opaque, stable Renewr UUID of the event. Use it in URL paths and in instruction payloads.
patentobjectThe patent this event belongs to, identified both ways.
patent.idstring (UUID)Renewr UUID of the patent.
patent.providerIdstring, nullableYour own matching reference for that patent; it lets you reconcile events without an extra lookup.
eventTypestring enum, openBusiness kind of the event. RENEWAL is the only kind today; new kinds will be added over time. See below.
dueDatestring, YYYY-MM-DDThe date the fee must be paid by.
gracePeriodEndDatestring YYYY-MM-DD, nullableEnd of the office's grace period. See Grace period.
renewalobject, nullableRenewal-specific identification, non-null exactly when eventType is RENEWAL (today: every event).
renewal.annuityYearintegerWhich year of the patent's life this fee pays for (e.g. year 5 of 20).
renewal.paymentSequenceNumberinteger, nullableThe office's payment sequence number, present only when it differs from annuityYear (offices with irregular payment cadences). null means "same as annuityYear".
appliedDecisionenum PROCEED | SKIP_THIS_TIME | DROP, nullableThe instruction that has been applied to this event; null while no instruction has been executed. See Instructions & instructability.
duePeriodenum UPCOMING | CURRENT | LATE | GRACE_PERIOD | LAPSED, nullableWhere the event sits relative to its deadline. See below.
processingStatusenum, nullableHow far Renewr has taken the event through its pipeline. See below.
processingStatusUpdatedAtstring ISO 8601, nullableTimestamp of the last processingStatus change.
isFxRateFrozenbooleantrue when the FX rate used to compute this event's fees is frozen. See Fees & FX.
feesStatusenum ESTIMATED | INVOICED, nullableWhether the fees for this event are projected (ESTIMATED) or final (INVOICED, meaning an invoice exists).
createdAtstring ISO 8601, nullableCreation timestamp.
updatedAtstring ISO 8601, nullableLast update timestamp.
instructabilityobjectWhether and how this event can be instructed right now. Present on every event endpoint. Covered in depth in Instructions & instructability.
feesobject, optionalEstimated 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 renewal sub-object is non-null exactly when eventType is "RENEWAL". Future event kinds will carry their own type-specific sub-object and a null renewal.
  • On the cross-portfolio list, you can pin your integration to renewals ahead of future kinds by passing eventTypes=RENEWAL to GET /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:

ValueMeaningWhat to do
UPCOMINGDue 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.
CURRENTDue within the normal instruction cycle (roughly one to two months out).Instruct now. This is the bucket a monthly cycle works through.
LATEDue imminently.Instruct urgently; the payment must go out.
GRACE_PERIODThe 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).
LAPSEDPast 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.

StatusOperational meaning
NOT_INSTRUCTEDDefault at event creation. Renewr is waiting for your decision.
INSTRUCTEDYour instruction was executed, set synchronously during the POST.
PAYMENT_SENTRenewr included the fee in a payment batch sent to the office or local agent.
PAYMENT_CONFIRMEDThe payment was confirmed received.
FULFILLEDTerminal, 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).
UNPROCESSABLETerminal, 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:

EndpointResponse shapeUse for
GET /api/v2/external/patents/{patentId}/eventsBare JSON array (no envelope, no pagination)All events of one patent.
GET /api/v2/external/patents/{patentId}/events/{eventId}Single objectOne event in full.
GET /api/v2/external/patents/{patentId}/events/{eventId}/feesSingle fees objectThe fee breakdown for one event (Fees & FX).
GET /api/v2/external/patent-eventsList envelope { pagination, data }Cross-portfolio: everything falling due in a window.
GET .../events/{eventId}/documents/*PDF binaryPer-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.

Renewr External API v2. Access on invitation.