Skip to main content
Once you have an API key, every request to the Enrichment API carries it in a single header.

The authentication header

Send your raw key in the X-Api-Client-Key header on every request:
curl https://api.verzla.com/api/enrichment/attribute-templates \
  -H "X-Api-Client-Key: sk_live_your_key_here"
The server hashes your key (SHA-256), looks up the matching API client, resolves the merchant organization, and updates the client’s lastUsedAt timestamp.
The key identifies both who you are and which merchant organization you operate on. You never pass an organization ID — it is derived from the key.

Scopes

Each endpoint requires a specific scope. Your key is granted one or more:
ScopeRequired by
catalog:readGET /attribute-templates, GET /products, GET /products/skus, GET /acceptance-rate
catalog:submitPOST /products/submissions

Responses to expect

401 Unauthorized
error
No key was sent, or the key is invalid / inactive. Check the X-Api-Client-Key header.
403 Forbidden
error
Your key is valid but lacks the scope the endpoint requires. The body names the missing scope, e.g. Missing required scope: catalog:submit.
400 Bad Request
error
The request itself is malformed — too many SKUs, an empty submission, a bad modifiedSince value, and so on. See each endpoint’s reference for specifics.

A reusable client

A thin wrapper keeps the key and base URL in one place:
const BASE = "https://api.verzla.com/api/enrichment";

function enrichmentFetch(path: string, init: RequestInit = {}) {
  return fetch(`${BASE}${path}`, {
    ...init,
    headers: {
      "X-Api-Client-Key": process.env.VERZLA_ENRICHMENT_KEY!,
      "Content-Type": "application/json",
      ...init.headers,
    },
  });
}

// Usage
const res = await enrichmentFetch("/attribute-templates");
const templates = await res.json();
Keep the key server-side. Because it grants read and write access to a merchant’s catalog, it must never reach a browser, mobile app, or any client you don’t fully control.