Skip to content

Sync (upsert) patents

POST /api/v2/external/patents/sync

Authentication: 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
FieldTypeRequiredDescription
externalImportRefstringNoIdempotence key for the import (same ref ⇒ replay).
itemsarray of objectsYesUpsert items, each triaged independently. No size limit; above 100 items the batch is processed asynchronously (202, poll the status endpoint).
items[].providerIdstring or nullNoThe client's own reference for the patent: a known reference updates the matching patent, an unknown one proposes a create.
items[].clientCaseReferencestring or nullNoCase reference on the client side.
items[].clientFamilyReferencestring or nullNoFamily reference on the client side.
items[].titlestring or nullNoTitle of the patent.
items[].officestringNoPatent office / authority code (WO, EP, EA, or an ISO 3166-1 national office code).
items[].patentTypestringNoOne of: PATENT, UTILITY, DESIGN.
items[].applicationNumberstringNoApplication (filing) number, as recorded in your portfolio (no normalization applied); the office-standard form lives in officialNumbers.
items[].applicationDatestringNoApplication (filing) date, strict YYYY-MM-DD.
items[].nationalPhaseEntryDatestring or nullNoPCT national phase entry date, strict YYYY-MM-DD.
items[].priorityDatestring or nullNoPriority date of the application, strict YYYY-MM-DD.
items[].publicationNumberstring or nullNoPublication number, as recorded in your portfolio.
items[].publicationDatestring or nullNoPublication date, strict YYYY-MM-DD.
items[].grantPublicationNumberstring or nullNoGrant publication number, as recorded in your portfolio.
items[].grantDatestring or nullNoGrant date, strict YYYY-MM-DD.
items[].pctApplicationNumberstring or nullNoPCT application number, as recorded in your portfolio.
items[].expirationDatestring or nullNoLegal expiration date, strict YYYY-MM-DD.
items[].extendedExpirationDatestring or nullNoExtended expiration date, strict YYYY-MM-DD.
items[].lapseDatestring or nullNoLapse date, strict YYYY-MM-DD.
items[].renewalsManagedFromstringNoDate renewals are managed from (filing or grant, depending on the office), strict YYYY-MM-DD: the base of the annuity computation.
items[].statusstring or nullNoShared IP right status. One of: PENDING, PUBLISHED, GRANTED, LAPSED.
items[].filingRoutestring or nullNoHow the title was filed. One of: NATIONAL, PCT, EP, EA, DIVISIONAL.
items[].applicantTypestring or nullNoOne of: MICRO, SMALL, LARGE.
items[].claimCountinteger or nullNoNumber of claims; 0 (or a negative number) is stored as null, i.e. unknown.
items[].designatedCountriesarray of string or nullNoISO 3166-1 alpha-2 designations (EP/regional).
items[].ownerstring or nullNoOwner (display).
items[].secondaryOwnersarray of string or nullNoCo-owners.
items[].subCasestring or nullNoSub-case.
items[].renewrPatentIdstring or nullNoRenewr 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
FieldTypeDescription
objectstringString describing the object type (auto-description). One of: patentSyncBatch.
importIdstringId of the import batch, the handle for the status endpoint. Format: uuid.
statusstringPENDING 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.
modestringSYNC (processed inline) or ASYNC (processed in the background). One of: SYNC, ASYNC.
totalItemsintegerNumber of items in the batch.
processedItemsintegerItems processed so far, whatever their outcome.
autoAppliedItemsintegerItems applied automatically (no critical field touched).
stagedItemsintegerItems staged for review. Counted at triage; the counter does not decrease when decisions are made.
rejectedItemsintegerItems rejected as invalid.
suppressedItemsintegerIdentical re-pushes of previously refused proposals.
createdAtstring or nullWhen the batch was received. Format: date-time.
completedAtstring or nullWhen the batch finished processing (null while PENDING or PROCESSING). Format: date-time.
resultsobjectPer-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.paginationobjectPagination metadata.
results.pagination.totalItemsintegerTotal number of items across all pages.
results.pagination.currentPageinteger1-based index of the current page.
results.pagination.itemsPerPageintegerNumber of items per page (server cap: 100).
results.pagination.totalPagesintegerTotal number of pages.
results.pagination.hasMorebooleanTrue when another page exists after the current one.
results.dataarray of objectsPage of results.
results.data[].providerIdstring or nullThe providerId of the item, echoed back (null when the item did not carry one).
results.data[].renewrPatentIdstring or nullRenewr 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[].actionstring or nullCREATE | UPDATE (null when rejected pre-match). One of: CREATE, UPDATE.
results.data[].outcomestringOne of: APPLIED, ACCEPTED, STAGED, SUPPRESSED, REJECTED.
results.data[].requestIdstring or nullStable 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[].reasonstring or nullWhy 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
FieldTypeDescription
objectstringString describing the object type (auto-description). One of: patentSyncBatch.
importIdstringId of the import batch, the handle for the status endpoint. Format: uuid.
statusstringPENDING 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.
modestringSYNC (processed inline) or ASYNC (processed in the background). One of: SYNC, ASYNC.
totalItemsintegerNumber of items in the batch.
processedItemsintegerItems processed so far, whatever their outcome.
autoAppliedItemsintegerItems applied automatically (no critical field touched).
stagedItemsintegerItems staged for review. Counted at triage; the counter does not decrease when decisions are made.
rejectedItemsintegerItems rejected as invalid.
suppressedItemsintegerIdentical re-pushes of previously refused proposals.
createdAtstring or nullWhen the batch was received. Format: date-time.
completedAtstring or nullWhen the batch finished processing (null while PENDING or PROCESSING). Format: date-time.
resultsobjectPer-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.paginationobjectPagination metadata.
results.pagination.totalItemsintegerTotal number of items across all pages.
results.pagination.currentPageinteger1-based index of the current page.
results.pagination.itemsPerPageintegerNumber of items per page (server cap: 100).
results.pagination.totalPagesintegerTotal number of pages.
results.pagination.hasMorebooleanTrue when another page exists after the current one.
results.dataarray of objectsPage of results.
results.data[].providerIdstring or nullThe providerId of the item, echoed back (null when the item did not carry one).
results.data[].renewrPatentIdstring or nullRenewr 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[].actionstring or nullCREATE | UPDATE (null when rejected pre-match). One of: CREATE, UPDATE.
results.data[].outcomestringOne of: APPLIED, ACCEPTED, STAGED, SUPPRESSED, REJECTED.
results.data[].requestIdstring or nullStable 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[].reasonstring or nullWhy 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.

StatusDescription
400Validation failed (validation_failed): carries per-field errors[] with RFC 6901 JSON Pointers.
401Missing or invalid API key (invalid_api_key), or expired key (api_key_expired).
403API key lacks the required scope (insufficient_scope, with requiredScope extension) or the operation is not enabled for this client (forbidden).
409The externalImportRef was already used with different items (conflict, with an existingBatchId extension).
429Daily 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"
      }
    ]
  }'

Renewr External API v2. Access on invitation.