RevKeen Docs
Api reference

Batch upsert products by external ID

Create or update multiple products by external system ID. Supports up to 100 products per request with stale update protection.


Related endpoints

  • GET /products — List products
  • POST /products — Create product
  • GET /products/{id} — Get product by ID
  • PATCH /products/{id} — Update product
  • PUT /products/external/{source}/{externalId} — Upsert product by external ID

Common errors

  • 400 invalid_request — malformed payload or failed validation.
  • 401 unauthenticated — missing, malformed, or revoked API key.
  • 403 permission_denied — key lacks the required scope, or the resource belongs to a different merchant.

Idempotency

Pass an Idempotency-Key header (UUID v4 recommended) to make retries safe. Keys are valid for 24 hours; see the idempotency guide.

PUT
/products/external/batch
x-api-key<token>

Your RevKeen API key (powered by Unkey). Get it from Dashboard > Settings > API Keys. Use rk_sandbox_* for test mode and rk_live_* for production.

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

curl -X PUT "https://api.revkeen.com/v2/products/external/batch" \  -H "x-api-key: $REVKEEN_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "source": "practicehub",    "products": [      {        "external_id": "prod_12345",        "name": "Monthly Membership",        "description": "string",        "kind": "subscription",        "amount_cents": 9900,        "currency": "USD",        "is_active": true,        "interval": "month",        "interval_count": 1,        "external_updated_at": "2026-01-01T00:00:00Z",        "external_ref": "string",        "metadata": {}      }    ]  }'
{
  "created": 5,
  "updated": 10,
  "skipped": 2,
  "failed": [
    {
      "external_id": "string",
      "error": "string"
    }
  ]
}
Empty
Empty
Empty