Centra — integration guide
Centra is a Swedish headless-commerce platform widely used across premium fashion and lifestyle brands. DPP Agent talks to Centra's Integration API (GraphQL) and treats each ProductSize leaf as a sellable SKU → one passport per GTIN.
What the adapter does, in one sentence
DPP Agent issues a single GraphQL query against Centra's
products(...) resolver, flattens the Product → Variant → ProductSize
tree into one DPP row per EAN/UPC, and writes the result through the
same conflict-aware pipeline used by every other adapter. Read-only,
no Centra-side schema changes, no write-back.
Authentication
Bearer token issued from Centra Admin → Integrations → Generate API token. Scope the token to the integration role with Product read and Variant read — nothing else.
POST <base_url>/graphql
Authorization: Bearer <token>
Content-Type: application/json
Credential handling
Identical envelope to the other adapters:
- AES-256-GCM encrypted at rest, master key in Vercel env vars only
- Redacted fingerprint in the UI; pasting a new value clears the old
- Decrypted in-memory for the duration of a single sync, then dropped
- Never echoed in logs, request traces, or audit payloads
- Revoke the token in Centra → next sync run fails cleanly with HTTP 401
Scope limitation
1. Read-only role on the Centra side
The token role needs only Product:read and Variant:read. No
write permissions are requested. Operationally this means our code is
incapable of mutating Centra inventory even under compromise.
2. Field allowlist baked into the query
The default products query asks Centra for an explicit field list — identifiers, brand, country of origin, sizes with EAN/UPC, media. We do not request:
- Pricing / margin / cost fields
- Stock levels
- Internal product notes or supply-chain narrative
- Customer order references
If your brand needs a different shape (e.g. extra attributes for an
AGEC-specific declaration), paste a custom GraphQL document into
settings.products_query. The adapter passes whatever you give it
through to Centra unchanged. The default is the smallest query that
still produces a valid DPP.
3. status_filter setting (optional)
settings.status_filter = "ACTIVE" restricts the query to live SKUs.
Combine with where: { archived: false } (via products_query
override) to exclude legacy variants entirely.
4. Network IP allowlist
DPP Agent's sync runs on Vercel. Centra's WAF can whitelist Vercel's published egress IP ranges to lock the API endpoint to our requests only. See Vercel regions.
Settings reference
| Setting | Required | Purpose |
|---|---|---|
base_url |
yes | https://<your-shop>.centra.com |
graphql_path |
no | Default /graphql |
page_size |
no | 50–200. Default 50 to stay under Centra's complexity ceiling. |
sync_mode |
no | skeleton (default) | full |
products_query |
no | Override GraphQL document. Defaults to the field-limited query. |
products_path |
no | Dot path in the response, default data.products. |
status_filter |
no | ACTIVE, etc. |
Sync semantics
Two modes:
- Skeleton (default) — IDs + GTIN + variant + media + status. Drops Centra's per-page complexity score from ~38k to ~3–5k so a 2,000-product catalogue completes inside Vercel's 300s function ceiling. Use for the first sync and for cron heartbeats.
- Full — adds product/variant attributes. Slower; recommended after the skeleton pass has validated the field mapping.
Conflict policy: drafts are overwritten; active DPPs spawn
dpp_revisions(status=pending) for review; withdrawn/archived/recalled
DPPs are skipped. Same rules as every other adapter.
Onboarding sequence
- Centra admin: create integration role with
Product:read+Variant:read, generate API token - Paste token +
base_urlinto DPP Agent → Integrations → Add Centra - Connection test (
Probe): adapter runs a single 1-page query and reports back the product + size count - Skeleton sync with
page_size = 50andsync_max_pages = 2-3 - Review the resulting draft DPPs in admin → tune
products_queryif any field is missing - Switch to full sync once mapping is locked
- Cron picks up the schedule — 6h default, configurable per tenant
Compliance hooks
The default query populates:
| ESPR field | Centra path |
|---|---|
espr.pid.gtin |
variants[].productSizes[].EAN | UPC | SKU |
espr.pid.product_name |
name |
espr.pid.product_brand |
brand.name |
espr.pid.commodity_code |
harmonizedCommodityCode (TARIC) |
espr.pid.country_of_origin |
countryOfOrigin.code |
espr.pid.color |
variants[].name |
espr.pid.size |
variants[].productSizes[].sizeNumber |
tex.product.hero_image_url |
media[].url (first item) |
Supply-chain / journey fields are not in Centra's standard model —
connect Delogue or TrusTrace alongside
for AGEC tex.journey.steps and material declarations.
Troubleshooting
- HTTP 401 on probe — token revoked or rotated in Centra
- HTTP 200 with
errors[]mentioning complexity — lowerpage_sizeor move tosync_mode = skeleton - Empty
data.products— token role lacksProduct:read, or thestatus_filterexcludes every row - GTIN missing on rendered DPPs — your variants don't carry EAN. Centra stores SKU as a fallback; we accept SKU but a true GS1 GTIN is what ESPR resolvers expect. Backfill EAN in Centra before launch.
- Slow sync hitting 300s ceiling — split via
sync_max_pagesand run incrementally; cron will catch up across runs
Open a ticket at support@dppagent.com with the integration ID and
the last sync log entry; one business day response.