Zugo: a complete sync app
Zugo is CIQRA’s reference app, and it uses only the public API described on this site — no private back door.
It reads a dealer’s used-car feed and publishes each vehicle into the store as a
metaobject entry of type ikinci-el-arac, with its photos
imported into the store’s media library.
Source: ciqra-saas/apps/Ciqra.Apps.Zugo/ in the CIQRA repository.
A one-shot process: it starts, syncs, and exits. It holds no state between runs — the store is the state, and every write is keyed so a re-run converges instead of duplicating.
Setting (Zugo: section) |
Purpose |
|---|---|
FeedBaseUrl, FeedUsername, FeedPassword |
The dealer feed. |
PlatformBaseUrl |
Where to reach the CIQRA API. |
PlatformHost |
The store’s domain, sent as Host — this is what selects the store. |
ClientId, ClientSecret |
The app’s credentials. |
MetaobjectType |
Default ikinci-el-arac. |
MaxRunDuration |
Default 6 hours. |
Missing secrets are all reported at startup at once, rather than one per failed run.
The calls, in order
Section titled “The calls, in order”- Token.
POST /apps/tokenwith the client credentials. The token is cached and re-requested one minute beforeexpiresInruns out. - Photos. For each vehicle,
POST /apps/media/importsin chunks of up to 100 URLs, withIdempotency-Key: zugo:{runId}:{vehicle}:{chunk}. The key is per run on purpose: within a run a retry replays instead of re-downloading; the next run is a new request and picks up changed photos. Deduplication by URL and by content hash makes unchanged photos cost nothing. - Entry.
PUT /custom-data/metaobjects/ikinci-el-arac/entries/{feed id}with the vehicle’s fields and the returnedmediaAssetIds in the gallery fields. The feed id is the handle, so the same car always lands on the same entry.
Failures are isolated per vehicle: one car whose photos fail does not stop the others, and the run’s summary
reports every one. 401, 403 and 404 each produce a distinct message naming the likely cause (bad
credentials, a missing scope, a missing metaobject type).
Scopes it asks for
Section titled “Scopes it asks for”write_media and write_metaobjects — nothing to do with orders or customers, so the merchant’s consent screen
shows exactly what it does.
What to copy
Section titled “What to copy”- Key every write by something stable from your source (handle = source id).
- Treat the batch routes’ per-row results as the truth, not the status code.
- Refresh the token before it expires instead of reacting to
401. - Keep idempotency keys per logical operation and reuse them across retries.