Appearance
Sync (upsert) patents
POST /api/v2/external/patents/syncAuthentication: x-api-key header, with the patents:write scope. See Authentication and limits.
Upsert 1..N patents, using the same field names read back from GET /patents. Each item is triaged independently: a non-critical update is applied immediately; a create or a critical update is staged for review; an invalid item is rejected; an identical re-push of a refused proposal is suppressed. Batches of up to 100 items are processed inline (201 with final outcomes); larger batches are processed in the background (202, poll the status endpoint with the returned importId). Idempotent on externalImportRef: the same reference with the same items replays the stored batch, and with different items answers 409. The API key needs the patents:write scope.
Request body
json
{
"externalImportRef": "ipms-2026-08-07-0001",
"items": [
{
"providerId": "ACME-2021-0042",
"title": "Heat exchanger with corrugated fins (amended claims)"
},
{
"providerId": "ACME-2019-0007",
"office": "FR",
"patentType": "PATENT",
"filingRoute": "NATIONAL",
"status": "GRANTED",
"title": "Modular battery pack housing",
"applicationNumber": "FR1902345",
"applicationDate": "2019-03-12",
"grantDate": "2022-06-01",
"renewalsManagedFrom": "2019-03-12"
}
]
}Body fields
| Field | Type | Required | Description |
|---|---|---|---|
externalImportRef | string | No | Idempotence key for the import (same ref ⇒ replay). |
items | array of objects | Yes | Upsert items, each triaged independently. No size limit; above 100 items the batch is processed asynchronously (202, poll the status endpoint). |
items[].providerId | string or null | No | The client's own reference for the patent: a known reference updates the matching patent, an unknown one proposes a create. |
items[].clientCaseReference | string or null | No | Case reference on the client side. |
items[].clientFamilyReference | string or null | No | Family reference on the client side. |
items[].title | string or null | No | Title of the patent. |
items[].office | string | No | Patent office / authority code (WO, EP, EA, or an ISO 3166-1 national office code). |
items[].patentType | string | No | One of: PATENT, UTILITY, DESIGN. |
items[].applicationNumber | string | No | Application (filing) number, as recorded in your portfolio (no normalization applied); the office-standard form lives in officialNumbers. |
items[].applicationDate | string | No | Application (filing) date, strict YYYY-MM-DD. |
items[].nationalPhaseEntryDate | string or null | No | PCT national phase entry date, strict YYYY-MM-DD. |
items[].priorityDate | string or null | No | Priority date of the application, strict YYYY-MM-DD. |
items[].publicationNumber | string or null | No | Publication number, as recorded in your portfolio. |
items[].publicationDate | string or null | No | Publication date, strict YYYY-MM-DD. |
items[].grantPublicationNumber | string or null | No | Grant publication number, as recorded in your portfolio. |
items[].grantDate | string or null | No | Grant date, strict YYYY-MM-DD. |
items[].pctApplicationNumber | string or null | No | PCT application number, as recorded in your portfolio. |
items[].expirationDate | string or null | No | Legal expiration date, strict YYYY-MM-DD. |
items[].extendedExpirationDate | string or null | No | Extended expiration date, strict YYYY-MM-DD. |
items[].lapseDate | string or null | No | Lapse date, strict YYYY-MM-DD. |
items[].renewalsManagedFrom | string | No | Date renewals are managed from (filing or grant, depending on the office), strict YYYY-MM-DD: the base of the annuity computation. |
items[].status | string or null | No | Shared IP right status. One of: PENDING, PUBLISHED, GRANTED, LAPSED. |
items[].filingRoute | string or null | No | How the title was filed. One of: NATIONAL, PCT, EP, EA, DIVISIONAL. |
items[].applicantType | string or null | No | One of: MICRO, SMALL, LARGE. |
items[].claimCount | integer or null | No | Number of claims; 0 (or a negative number) is stored as null, i.e. unknown. |
items[].designatedCountries | array of string or null | No | ISO 3166-1 alpha-2 designations (EP/regional). |
items[].owner | string or null | No | Owner (display). |
items[].secondaryOwners | array of string or null | No | Co-owners. |
items[].subCase | string or null | No | Sub-case. |
items[].renewrPatentId | string or null | No | Renewr UUID of the patent; forces an update of that exact patent (an unknown UUID rejects the item, it never creates). Format: uuid. |
Response
201 The batch with per-item outcomes (inline processing).
json
{
"object": "patentSyncBatch",
"importId": "2e7a9c40-5b1d-4f8e-9a3c-6d0e1f2a3b4c",
"status": "TRIAGED",
"mode": "SYNC",
"totalItems": 2,
"processedItems": 2,
"autoAppliedItems": 1,
"stagedItems": 1,
"rejectedItems": 0,
"suppressedItems": 0,
"createdAt": "2026-08-07T06:10:00.000Z",
"completedAt": "2026-08-07T06:10:02.000Z",
"results": {
"pagination": {
"totalItems": 2,
"currentPage": 1,
"itemsPerPage": 100,
"totalPages": 1,
"hasMore": false
},
"data": [
{
"providerId": "ACME-2021-0042",
"renewrPatentId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"action": "UPDATE",
"outcome": "APPLIED",
"requestId": "2a6c3580-e95f-4780-a845-9200241b5a00",
"reason": null
},
{
"providerId": "ACME-2019-0007",
"renewrPatentId": null,
"action": "CREATE",
"outcome": "STAGED",
"requestId": "aa6ea540-56f6-4c00-a66b-4c0074d78c00",
"reason": null
}
]
}
}Response fields
| Field | Type | Description |
|---|---|---|
object | string | String describing the object type (auto-description). One of: patentSyncBatch. |
importId | string | Id of the import batch, the handle for the status endpoint. Format: uuid. |
status | string | PENDING and PROCESSING: the batch is still being processed. TRIAGED: every item has an outcome, at least one awaits review. SETTLED: nothing left to wait on. ERROR: at least one item could not be recorded; contact support with the importId. One of: PENDING, PROCESSING, TRIAGED, SETTLED, ERROR. |
mode | string | SYNC (processed inline) or ASYNC (processed in the background). One of: SYNC, ASYNC. |
totalItems | integer | Number of items in the batch. |
processedItems | integer | Items processed so far, whatever their outcome. |
autoAppliedItems | integer | Items applied automatically (no critical field touched). |
stagedItems | integer | Items staged for review. Counted at triage; the counter does not decrease when decisions are made. |
rejectedItems | integer | Items rejected as invalid. |
suppressedItems | integer | Identical re-pushes of previously refused proposals. |
createdAt | string or null | When the batch was received. Format: date-time. |
completedAt | string or null | When the batch finished processing (null while PENDING or PROCESSING). Format: date-time. |
results | object | Per-item outcomes in POST-body order, as the standard v2 list envelope. The GET paginates them (?currentPage=&itemsPerPage=, page size capped at 100); the POST answers with the first page (all outcomes of an inline batch, empty while an async batch is pending). |
results.pagination | object | Pagination metadata. |
results.pagination.totalItems | integer | Total number of items across all pages. |
results.pagination.currentPage | integer | 1-based index of the current page. |
results.pagination.itemsPerPage | integer | Number of items per page (server cap: 100). |
results.pagination.totalPages | integer | Total number of pages. |
results.pagination.hasMore | boolean | True when another page exists after the current one. |
results.data | array of objects | Page of results. |
results.data[].providerId | string or null | The providerId of the item, echoed back (null when the item did not carry one). |
results.data[].renewrPatentId | string or null | Renewr UUID of the target patent. Null when no patent is attached yet: rejected before matching, or a create still awaiting review (an accepted create carries the UUID of the new patent on later polls). |
results.data[].action | string or null | CREATE | UPDATE (null when rejected pre-match). One of: CREATE, UPDATE. |
results.data[].outcome | string | One of: APPLIED, ACCEPTED, STAGED, SUPPRESSED, REJECTED. |
results.data[].requestId | string or null | Stable id of the change request recorded for this item; quote it in support requests (null only when the item could not be recorded). Format: uuid. |
results.data[].reason | string or null | Why the item was rejected or suppressed; for a proposal refused during review, the reviewer reason verbatim (null otherwise). |
202 The batch was accepted and is processed in the background; poll the status endpoint for outcomes.
json
{
"object": "patentSyncBatch",
"importId": "2e7a9c40-5b1d-4f8e-9a3c-6d0e1f2a3b4c",
"status": "PENDING",
"mode": "ASYNC",
"totalItems": 250,
"processedItems": 0,
"autoAppliedItems": 0,
"stagedItems": 0,
"rejectedItems": 0,
"suppressedItems": 0,
"createdAt": "2026-08-07T06:10:00.000Z",
"completedAt": null,
"results": {
"pagination": {
"totalItems": 0,
"currentPage": 1,
"itemsPerPage": 100,
"totalPages": 0,
"hasMore": false
},
"data": []
}
}Response fields
| Field | Type | Description |
|---|---|---|
object | string | String describing the object type (auto-description). One of: patentSyncBatch. |
importId | string | Id of the import batch, the handle for the status endpoint. Format: uuid. |
status | string | PENDING and PROCESSING: the batch is still being processed. TRIAGED: every item has an outcome, at least one awaits review. SETTLED: nothing left to wait on. ERROR: at least one item could not be recorded; contact support with the importId. One of: PENDING, PROCESSING, TRIAGED, SETTLED, ERROR. |
mode | string | SYNC (processed inline) or ASYNC (processed in the background). One of: SYNC, ASYNC. |
totalItems | integer | Number of items in the batch. |
processedItems | integer | Items processed so far, whatever their outcome. |
autoAppliedItems | integer | Items applied automatically (no critical field touched). |
stagedItems | integer | Items staged for review. Counted at triage; the counter does not decrease when decisions are made. |
rejectedItems | integer | Items rejected as invalid. |
suppressedItems | integer | Identical re-pushes of previously refused proposals. |
createdAt | string or null | When the batch was received. Format: date-time. |
completedAt | string or null | When the batch finished processing (null while PENDING or PROCESSING). Format: date-time. |
results | object | Per-item outcomes in POST-body order, as the standard v2 list envelope. The GET paginates them (?currentPage=&itemsPerPage=, page size capped at 100); the POST answers with the first page (all outcomes of an inline batch, empty while an async batch is pending). |
results.pagination | object | Pagination metadata. |
results.pagination.totalItems | integer | Total number of items across all pages. |
results.pagination.currentPage | integer | 1-based index of the current page. |
results.pagination.itemsPerPage | integer | Number of items per page (server cap: 100). |
results.pagination.totalPages | integer | Total number of pages. |
results.pagination.hasMore | boolean | True when another page exists after the current one. |
results.data | array of objects | Page of results. |
results.data[].providerId | string or null | The providerId of the item, echoed back (null when the item did not carry one). |
results.data[].renewrPatentId | string or null | Renewr UUID of the target patent. Null when no patent is attached yet: rejected before matching, or a create still awaiting review (an accepted create carries the UUID of the new patent on later polls). |
results.data[].action | string or null | CREATE | UPDATE (null when rejected pre-match). One of: CREATE, UPDATE. |
results.data[].outcome | string | One of: APPLIED, ACCEPTED, STAGED, SUPPRESSED, REJECTED. |
results.data[].requestId | string or null | Stable id of the change request recorded for this item; quote it in support requests (null only when the item could not be recorded). Format: uuid. |
results.data[].reason | string or null | Why the item was rejected or suppressed; for a proposal refused during review, the reviewer reason verbatim (null otherwise). |
Errors
Errors use the application/problem+json envelope with stable machine-readable codes. See the Errors guide.
| Status | Description |
|---|---|
| 400 | Validation failed (validation_failed): carries per-field errors[] with RFC 6901 JSON Pointers. |
| 401 | Missing or invalid API key (invalid_api_key), or expired key (api_key_expired). |
| 403 | API key lacks the required scope (insufficient_scope, with requiredScope extension) or the operation is not enabled for this client (forbidden). |
| 409 | The externalImportRef was already used with different items (conflict, with an existingBatchId extension). |
| 429 | Daily API call limit exceeded (rate_limit_exceeded): the Retry-After header gives the seconds until reset. |
Example request
bash
curl -X POST "https://api.renewr.example/api/v2/external/patents/sync" \
-H "x-api-key: $RENEWR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"externalImportRef": "ipms-2026-08-07-0001",
"items": [
{
"providerId": "ACME-2021-0042",
"title": "Heat exchanger with corrugated fins (amended claims)"
},
{
"providerId": "ACME-2019-0007",
"office": "FR",
"patentType": "PATENT",
"filingRoute": "NATIONAL",
"status": "GRANTED",
"title": "Modular battery pack housing",
"applicationNumber": "FR1902345",
"applicationDate": "2019-03-12",
"grantDate": "2022-06-01",
"renewalsManagedFrom": "2019-03-12"
}
]
}'