Skip to content
Qrivo Docs

Merchant API

Authenticate merchant-owned systems, use the Qrivo API, and handle responses safely.

Merchant API access is intended for eligible merchants connecting a trusted server-side system to their own Qrivo workspace. A key can access only the Shopify store that created it.

Create an API key

  1. Open Qrivo → Settings and find the Merchant API section.
  2. Enter a name that identifies the integration.
  3. Select only the scopes the integration needs.
  4. Create the key and copy the token immediately.
  5. Store the token in a server-side secret manager.

Tokens are shown once

If you lose a token, revoke that key and create a replacement. Never place a token in a URL, storefront script, browser bundle, repository, screenshot, or log.

Scopes

ScopeAllows
qr:readList and read QR codes.
qr:writeCreate QR codes.
qr:manageUpdate dynamic QR codes.
campaigns:readList and read campaigns.
campaigns:writeCreate and update campaigns.
analytics:readRead the analytics summary.
webhooks:readList webhook subscriptions.
webhooks:writeCreate and delete webhook subscriptions.

Make a request

The production API origin is https://app.qrivo.solidcraftlabs.com. API routes are versioned under /api/v1. Use that origin for live integrations. Settings shows the origin for the current install if you are on a non-production environment.

export QRIVO_API_ORIGIN=https://app.qrivo.solidcraftlabs.com

curl "$QRIVO_API_ORIGIN/api/v1/qr-codes" \
  --header "Authorization: Bearer $QRIVO_API_TOKEN" \
  --header "Accept: application/json"

For JSON requests, also send Content-Type: application/json.

Endpoint reference

Method and pathScopeBehavior
GET /api/v1/qr-codesqr:readLists the shop's QR codes and a continuation cursor when present.
POST /api/v1/qr-codesqr:writeCreates a static or dynamic QR within the active plan quota.
GET /api/v1/qr-codes/:idqr:readReturns one QR code owned by the shop.
PATCH /api/v1/qr-codes/:idqr:manageUpdates an eligible dynamic QR code. Static codes are immutable.
GET /api/v1/campaignscampaigns:readLists the shop's campaigns.
POST /api/v1/campaignscampaigns:writeCreates a campaign.
GET /api/v1/campaigns/:idcampaigns:readReturns one campaign owned by the shop.
PATCH /api/v1/campaigns/:idcampaigns:writeUpdates a campaign's name, description, or status.
GET /api/v1/webhookswebhooks:readLists subscriptions without returning signing secrets.
POST /api/v1/webhookswebhooks:writeCreates a subscription for a public HTTPS endpoint.
DELETE /api/v1/webhooks/:idwebhooks:writeDeletes a subscription.
GET /api/v1/analytics/summaryanalytics:readReturns a summary of QR, scan, and campaign activity.

Examples

Create a dynamic QR code

The destination must be an eligible HTTPS URL for the authenticated store. Use static only when you need a permanent, non-trackable destination.

curl "$QRIVO_API_ORIGIN/api/v1/qr-codes" \
  --request POST \
  --header "Authorization: Bearer $QRIVO_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "destination": "https://your-store.myshopify.com/products/example",
    "note": "Fall window display",
    "qrType": "dynamic"
  }'

Pause a dynamic QR code

curl "$QRIVO_API_ORIGIN/api/v1/qr-codes/$QR_ID" \
  --request PATCH \
  --header "Authorization: Bearer $QRIVO_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"status":"paused"}'

Create a campaign

curl "$QRIVO_API_ORIGIN/api/v1/campaigns" \
  --request POST \
  --header "Authorization: Bearer $QRIVO_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Fall retail launch",
    "description": "QR placements for the fall collection"
  }'

Responses and errors

Successful JSON responses use a top-level data field. Lists may also include nextCursor. Error responses include a stable error value and may include a human-readable message.

StatusMeaningRecommended action
200, 201, 204Read/update, created, or deleted successfullyProcess the response. A 204 response has no useful body.
400Request body, URL, or destination is invalidCorrect the request; do not retry it unchanged.
401Token is missing, invalid, or revokedCheck the server-side secret or replace the key.
403Plan or API-key scope does not allow the actionUse an appropriately scoped key or review the plan.
404Route or shop-owned record does not existCheck the path and record ID.
409A plan limit or state conflict prevents the actionReview the limit or avoid modifying a static code.
429The shop exceeded its current request windowWait until the current minute ends, then retry with backoff.

Successful authenticated responses expose ratelimit-remaining and ratelimit-reset. The reset value is a Unix timestamp in seconds. 429 responses do not currently include those headers. Rate limits and plan quotas are separate controls; consult Qrivo's Plans screen for current limits.

Security checklist

  • Create separate keys for separate systems and environments.
  • Use the smallest possible scope set.
  • Rotate keys after suspected exposure and revoke unused keys.
  • Apply timeouts, bounded retries, and idempotency.
  • Avoid logging complete requests that may contain tokens or private notes.
  • Never expose the API through untrusted client-side code without your own authenticated server.