Zid Docs
Apps
ThemesPayments
Apps
ThemesPayments
Help Center
Telegram Community
  1. Authorization
  • πŸ—‚οΈ Overview
  • πŸš€ Start Here
  • Responses
  • Rate Limiting
  • Embedded Apps
  • StoreFront Events
  • Zid MUI
  • Zid SDKs
  • Our custom MCP server
  • Zid AI Agent Skill
  • Build an app
    • Create your First App
    • Justifying your scopes
    • Test your app before you submit
    • Submitting your app for review
    • Plans & billing
      • Plans and pricing
      • Creating a plan
      • Usage-based plans
      • Private plans
      • Subscription and app events
      • Changing a plan
  • Authorization
    • Authorization
    • Public Apps OAuth Requirements
    • OAuth Errors & Troubleshooting
    • Zid Bridge Tool
  • Merchant APIs
    • Account
      • Me
        • Me
      • Store
        • Store
        • Branding
        • Localization
        • Social
        • Operations
        • Business
        • Upload Logo Image
        • Delete Logo Image
        • Upload Icon Image
        • Delete Icon Image
        • Upload Cover Image
        • Delete Cover Image
    • Orders
      • Order Tags
        • List Order Tags
        • Create Order Tag
      • Validate Order Request
      • Create Order
      • Change Order Status
      • Add Order Comment
      • View Order
      • List Orders
      • List Custom Order Statuses
      • List Order Credit Notes
      • Get Orders Highlights
      • Order Fulfillment Inventories
      • Bulk Create/Update Custom Order Statuses
    • Reverse Orders
      • Create Reverse Orders
      • Create Reverse Orders Waybill
      • Add Reverse Order Reasons
      • List Reverse Reasons
      • Calculate Reverse Totals
      • Create refund for reverse order
      • Upload bank transfer receipt
      • Update return products
      • Order Details – View for Return
    • Abandoned Carts
      • List Carts
      • View Cart
      • Validate Abandoned Cart Messages
      • Send Abandoned Cart Notification Manually
    • Products
      • Managing Products
        • Create Product Types
        • Create Product
        • List Products
        • View Product
        • List Product Settings
        • Update Product
        • Bulk Update Products
        • Delete Product
      • Digital Vouchers
        • List Vouchers
        • Order Vouchers
        • Create Voucher
        • Import Vouchers
        • Export Vouchers
        • Update Voucher
        • Remove Voucher
      • Product Categories
        • List Categories
        • View Category
        • Create Category
        • Create Subcategory
        • Update Category
        • Assign Product to Category
        • Bulk Assign Products to Category
        • Publish Category
        • Detach Category from All Products
        • Remove Product from Category
        • Set Categories Nesting
        • Delete Category Cover Image
        • Upload Category Cover Image
        • Delete Category
        • Delete Category Image
        • Upload Category Image
        • Update Category
      • Product Brands
        • List Brands
        • Single Brand
      • Product Badge
        • List Badges
      • Product Attributes
        • List Attributes
        • View Attribute
        • Create Attribute
        • Update Attribute
        • Delete Attribute
      • Product Attribute Presets
        • List Presets
        • Create Preset
        • Update Preset
        • Delete Preset
      • Product Variants
        • Create Variants
        • Create Custom Option
        • Update Custom Option
        • Delete Custom Option Field
        • Create Custom Input Field
        • Update Custom Input Field
        • Delete Custom Input Field
      • Product Sorting
        • Set Manual Product Order
        • Reset Manual Product Order
      • Product Images
        • List Images
        • Upload Image
        • Update Image Order
        • Delete Image
      • Product Availability Notifications
        • Notification Stats
        • Noticiation Settings
        • List Notifications
        • Create Notification
        • Update Settings
        • Send Notification Email
        • Export Notifications
      • Product Export
        • Email All Products to Store Owner
        • Import Products via CSV or xlsx File
      • Product Stock
        • Retrieve Product Stock
        • List Product Stock Records
        • Create Product Stock
        • Update Product Stock
        • Bulk Update Product Stock Records
      • Product Questions & Answers
        • Retrieve Product Question
        • Retrieve Product Answer
        • List Product Questions
        • List Answers for Question
        • Create Product Question
        • Create Product Answer
        • Update Product Question
        • Update Product Answer
        • Delete Product Question
        • Delete Product Answer
        • List Store Product Questions
      • Product Reviews
        • List Reviews
        • Count Reviews
      • Digital Products
        • Create Downloadable Product
        • Generate Upload URL
        • Upload File to S3
        • Create Product Downloadable
        • Get Product Downloadables
        • Delete Product Downloadable
        • List Store Downloadables
        • Create Store Downloadable
        • Delete Store Downloadable
    • Inventories
      • Create Location
      • Update Location
      • Update Product Stock for Location
      • List Locations
      • View Location
    • Shipping
      • List Store Shipping Methods
    • Marketing
      • Coupons
        • List Coupons
        • View Coupon
        • Create Coupon
        • Generate Bulk Coupons
        • Duplicate Coupon
        • Duplicate Bulk Coupons
        • Update Coupon Note
        • Update Coupon
        • Update Bulk Coupons
        • Update Coupon Status
        • Update Bulk Coupons Status
        • Delete Coupon
        • Delete Bulk Coupons
      • Bundle Offers
        • List Bundle Offers
        • View Bundle Offer
        • Create Bundle Offer
        • Update Bundle Offer
        • Delete Bundle Offer
        • Bulk Delete Bundle Offers
      • Loyalty Program
        • Loyalty Program Status
        • Loyalty Program Details
        • Loyalty Program Info
        • Customer Loyalty Summary
        • Customer Points History
        • Activate Loyalty Program
        • Set Points Expiration Rules
        • Update Cashback Rule
        • Create Points Redemption Method
        • Update Points Redemption Method
        • Delete Points Redemption Method
        • Adjust Customer Points
        • Update Redemption Method Status
        • Loyalty Program Analytics
        • Loyalty Program Settings
      • Customer Wallets
        • Cashback Rules
          • List Cashback Rules
          • Create Cashback Rule
          • Retrieve Cashback Rule
          • Update Cashback Rule
          • Delete Cashback Rule
        • Wallet Analytics
          • Get Wallet Analytics
          • Get Wallet Analytics by Rule
        • Manager Customer Wallet
          • List Customer Wallets
          • Bulk Credit Customer Wallets
          • Bulk Debit Customer Wallets
          • Export Customer Wallets
          • Get Customer Wallet Balance
          • Credit Customer Wallet
          • Debit Customer Wallet
          • Customer Pending Cashbacks
          • Customer Wallet Transactions
    • Customers
      • Customer Tags
        • List Customer Tags
        • Add Customer Tag
        • Ω’Update Customer Tag
        • Delete Customer Tag
      • Customer Portal Tickets
        • List Customer Portal Tickets
        • Customer Portal Ticket Detail
      • List Customers
      • View Customer
      • Primary Customer List
      • FInd Customer By Phone Number
      • Customer Profile
      • Add Customer
      • Update Customer
      • Delete Customer
      • Add Bulk Customers
      • Import Customers
    • Store Settings
      • πŸ“„ User Roles and Permissions
      • Retrieve Store Manager Profile
      • Retrieve VAT Settings
      • List Payment Methods
      • List Store Operating Countries
      • OneSignal Store Settings
      • Create or Update OneSignal Store Settings
      • Get Payment Options
    • Countries and Cities
      • List Countries
      • List Cities for Country
    • Blogs
      • Settings
        • Create
        • List
      • Categories
        • Create
        • List
        • Bulk Activate
        • Bulk Deactivate
        • Bulk Delete
        • Retrieve
        • Destroy
        • Partial Update
        • Bulk Add To Posts
        • Bulk Remove From Posts
        • Bulk Delete Blog Categories
      • Posts
        • Media
          • List
          • Create
          • Destroy
        • Create
        • List
        • Retrieve
        • Partial Update
        • Destroy
        • Archive
        • Publish
        • Bulk Archive
        • Bulk Publish
        • Bulk Delete
        • Export Posts
        • Import Template
        • Import Posts
      • Tags
        • Create
        • List
        • Retrieve
        • Partial Update
        • Destroy
        • Bulk Delete Tags
        • Bulk Add To Posts
        • Bulk Remove From Posts
      • Storefront
        • Posts
          • List
          • Retrieve
        • Categories
          • List
          • Retrieve
        • Tags
          • List
  • Webhooks
    • Overview
    • Webhook Health Tracking
    • Events
      • Order
      • Product
      • Abandoned Cart
      • Customer
      • Product Category
    • APIs
      • Health Summary
      • Broken Webhooks
      • Recover Broken Webhooks
      • List Webhooks
      • Create Webhook
      • Delete Webhook
      • Delete Webhook By subscriber
  • App Management
    • Events
    • APIs
      • Subscription Details
      • Update Usage-Based Charges
  1. Authorization

Authorization

OAuth 2.0 is the industry-standard protocol for authorizing apps, allowing secure access to resources without exposing sensitive data like passwords. It differs from authentication, which verifies the identity of the user or app.

Understanding OAuth 2.0 at Zid#

At Zid, we use the authorization code grant
type, which is ideal for confidential clients. This method involves redirecting the user to
an authorization server, where they grant permissions to your app. Your server-side app
must handle this process, as it requires securely managing the Client Secret.
PKCE is not used. Zid's authorization code grant is for confidential clients only.
Do not send code_challenge / code_verifier β€” they are ignored. Protect the
authorization request with the state parameter instead (see step 2).

Key Concepts in Zid's OAuth 2.0 Flow#

Authorization Token β€” grants your app access to the Zid API. Sent as
Authorization: Bearer <token>.
X-MANAGER-TOKEN β€” grants access to one specific store on the Zid platform. It adds an
extra layer of security when interacting with store-specific resources.
Access-Token β€” the same value as X-MANAGER-TOKEN. The token endpoint returns it under
the JSON key access_token, and Product-component endpoints accept it under the header
name Access-Token for historical reasons.
One value, three names. The token endpoint returns it as access_token. Send it as
X-Manager-Token (preferred) or Access-Token β€” the API checks for
X-MANAGER-TOKEN first and falls back to Access-Token. Never send both with different
values.

Important Requirements#

πŸ’‘ Your app must run server-side because it needs to securely store the Client Secret
during this process.
πŸ’‘ Almost every API request requires both the Authorization and X-Manager-Token
headers. One without the other fails.
πŸ’‘ Always send Accept-Language: en (or ar) explicitly. If the header is missing or
holds any other value, Zid replies in Arabic
β€” including error messages. Only ar and
en are recognised.

What's the difference between Authorization token and X-MANAGER-TOKEN?#

The Authorization token permits you to access the Zid API; X-MANAGER-TOKEN permits you to
access a particular store.

What's the difference between X-MANAGER-TOKEN and Access-Token?#

There is no difference between them. We use Access-Token with Product-component API
endpoints for technical reasons.

Base URIs#

When developing apps on Zid, you'll work with two main URIs:
1.
Base API URL β€” for resources like orders, products and coupons:
https://api.zid.sa/v1
2.
Base OAuth Server URL β€” for app authorization:
https://oauth.zid.sa
πŸ’‘ The latest version of our API is v1. Older versions are deprecated and should not be used.

Benefits of Using OAuth 2.0 with Zid#

Secure Access β€” your app accesses Zid resources without ever handling merchant passwords.
Scoped Permissions β€” scopes define exactly what your app may touch, and the merchant
sees and approves that list.
Token-Based Authentication β€” tokens are time-limited and individually revocable.
Merchants can revoke access at any time by uninstalling your app.

Implement OAuth 2.0 in your app#

1 β€” Generate Client ID and Client Secret#

Your Client ID and Client secret identify your app during the authorization
process. You get them when you create an app, and you can retrieve them at any time
afterwards.
For a new app
1.
Log in to your Partner Dashboard.
2.
Go to Apps β†’ All Apps β†’ Create Application.
3.
Choose the type of app you want to create, enter the app name, app URL, and allowed
redirection URLs, then create the app.
4.
Open the General settings tab and scroll to API keys.
For an app that already exists
1.
Go to Apps β†’ All Apps.
2.
Click the edit (pencil) icon on the app's row.
3.
Open the General settings tab and scroll to API keys.
Under API keys you will find three values:
FieldWhat it is
OAuth 2.0 endpointhttps://oauth.zid.sa β€” the base OAuth Server URL
Client IDYour client_id
Client secretYour client_secret. Masked by default; use the eye icon to reveal it and the copy icon to copy it.
Use the copy icon rather than selecting the text by hand β€” these values are long, and a
truncated or whitespace-padded secret fails at the token exchange with a generic
"Client authentication failed".
The redirect_uri you send later must match one of the allowed redirection URLs
exactly
β€” scheme, host, port, path, and trailing slash. A mismatch fails at the token
exchange, not at the redirect, which makes it easy to misdiagnose. See
Authorization Errors & Troubleshooting.

2 β€” Redirect (Ask for merchant permission)#

Screen Shot 2022-02-22 at 4.47.26 PM.png
The installation process starts in your application via the redirection URL, followed by
these steps:
1.
The browser is redirected to the Authorize endpoint of the OAuth Server (Zid AppMarket).
2.
If the merchant isn't authenticated, the OAuth Server redirects to the Login page.
3.
The merchant authenticates and is redirected back to the OAuth Server.
4.
The merchant sees the scopes your application is requesting and approves (or declines).
5.
The OAuth Server issues a one-time token called an Authorization Code, which is sent
to your application in the next step.
Parameters:
ParameterRequiredDescription
client_idyesYour application's client id from the Partner Dashboard
redirect_uriyesAn endpoint your application implements; must exactly match an allowed redirection URL
response_typeyescode
statestrongly recommendedOpaque random value. Zid returns it unchanged on both approval and denial. Compare it in your callback to reject forged requests.
If nothing happens when you open the authorize URL, the merchant is probably not
logged in. Zid redirects an unauthenticated merchant to their dashboard
(…/apps/{app_id}, or the shipping-providers page for shipping apps) rather than
returning an error. Have the merchant sign in to their store first, then retry.
Zid AppMarket supports many scopes. Select the ones your application needs on your
application page in the Partner Dashboard.
Changing scopes after merchants have installed your app has consequences. Adding a
scope puts every existing installation into a pending consent state until that merchant
re-approves. Endpoints covered by already-approved scopes keep working; endpoints needing
the new scope return 403 APP_PERMISSIONS_PENDING_APPROVAL. If your app holds a
wildcard token, adding a scope withholds the app entirely for that merchant
until they
re-approve.
The merchant re-approves by deactivating and reactivating your app from their
dashboard. Reactivation issues a fresh token pair carrying every current scope, so you
must be ready to receive and store new tokens
at that moment. See
Authorization Errors & Troubleshooting.

3 β€” Callback Method (Get the tokens)#

Screen Shot 2022-02-22 at 4.51.40 PM.png
1.
Our OAuth server sends the code to your pre-defined callback method.
2.
Your app backend makes a POST request to the Token endpoint with the Authorization
Code and your Client Credentials.
3.
The OAuth Server validates the code and the credentials, and returns an access token
and a refresh token.
4.
Your app stores the returned tokens for future use.
⏱️ The authorization code is valid for 10 minutes and can be used once. Exchange it
immediately in the callback request. Do not queue the exchange for a background worker,
and do not retry with the same code after a failure β€” request a fresh one by restarting
the flow.
Note: In all examples the payload is sent in the request body, not as query parameters.
The response holds everything you need to authenticate against that merchant's store:
{
  "token_type": "Bearer",
  "expires_in": 94608000,
  "authorization": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
  "access_token": "eyJpdiI6Ii8vZ...",
  "refresh_token": "def5020035c1f..."
}
FieldWhat it isWhere it goes
authorizationThe Authorization token (a JWT)Authorization: Bearer <authorization>
access_tokenThe store's manager tokenX-Manager-Token: <access_token>
refresh_tokenUsed to obtain a new token pairYour token store only
expires_inLifetime of authorization in secondsCompute the expiry and persist it
token_typeAlways Bearerβ€”
⚠️ expires_in is a number of seconds, not a date. Newly issued Authorization
tokens are valid for 3 years (31536000 Γ— 3 = 94608000 seconds). Still persist
now + expires_in from the response you actually received rather than hard-coding the
number β€” tokens issued before mid-2025 carry a shorter 1-year expiry, and the value can
change again.

Authorization token#

The Authorization token is generated by our OAuth 2.0 server: once a merchant installs your
application you receive it via the callback. Send it as the Authorization header on every
outgoing request.
All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API
requests without authentication will also fail β€” see
Authorization Errors & Troubleshooting.

X-Manager-Token (access_token)#

This token is an extra layer of security and must be sent alongside the Authorization
token:
Pass the content of access_token under the name X-Manager-Token, together with
Authorization, on every request.
The manager token is issued with the same expiry as the Authorization token β€” 3 years
for newly issued tokens. Treat expires_in from the token response as authoritative for
both, and store both together.
The data returned by this endpoint must be kept in secure storage. Abusing tokens may
result in your app being blocked.

Token lifetimes#

TokenLifetimeNotes
Authorization code10 minutes, single useExchange it immediately
authorization (access token)3 yearsTokens issued before mid-2025 carry 1 year β€” always read expires_in
access_token (X-Manager-Token)Same expiry as the Authorization tokenReissued on every refresh
refresh_token1 yearExpires two years before the access token
🚨 The refresh token expires two years before the access token. This is the single most
common way Zid integrations die.
A partner who refreshes "reactively, when a request returns 401" never refreshes at
all.
The access token is still perfectly valid at month 12, so no 401 ever arrives β€”
while the refresh token silently expires. Two years later the access token dies too, and
by then there is no way to recover the installation: the only path back is asking every
affected merchant to reinstall your app.
Refresh on a schedule, not on an error. Run a cron job that refreshes every merchant
roughly every 10 months, regardless of whether anything has failed. This is the single
most important operational rule on this page.

4 β€” Refresh#

Sooner or later your tokens expire. Refresh them well before they do:
The response has the same shape as the authorization-code response. Three rules:
1.
A refresh returns a new refresh_token, and revokes the old one. Persist the whole
new token set atomically. If you keep the old refresh token, your next refresh fails.
2.
It also returns a new access_token (X-Manager-Token). Replace the stored manager
token too, not just the authorization value.
3.
A failed refresh is not always retryable. If it fails because the merchant
uninstalled your app, retrying will never succeed β€” see
Authorization Errors & Troubleshooting.

Handling Errors#

Authorization can fail at three different places, each with its own error format:
WhereWhat you get
The authorize redirectThe merchant's browser lands on their dashboard with ?error_code=EC1…EC5
The token endpointA JSON error body β€” in two possible shapes
An API requestZid's standard error envelope with a message.code
Every code, its cause, and the exact fix are documented in
Authorization Errors & Troubleshooting.
The three you will hit most often:
401 with no message.code and a "scope" message β€” your token is missing a scope.
Do not refresh; refreshing returns a token with the same missing scope and loops.
403 APP_PERMISSIONS_PENDING_APPROVAL β€” you added a scope and this merchant has not
approved it yet. Only the merchant can clear this.
401 ERROR_SESSION_INVALID that survives a refresh β€” the merchant uninstalled your
app. Stop retrying and mark the installation inactive.
When a merchant uninstalls your app we send an app.market.application.uninstall
webhook, and every token you hold for that store is revoked immediately β€” the
Authorization token, the refresh token, and the X-Manager-Token.

Security and Best Practices#

Validate state β€” generate a random state per authorization request and reject any
callback whose state does not match. The live Zid OAuth server echoes it back for exactly
this purpose.
Keep the Client Secret server-side β€” never ship it in a browser bundle, a mobile app, or
a public repository. Rotate it immediately if it leaks.
X-MANAGER-TOKEN β€” keep it as secure as the Authorization token; it grants access to a
specific store's resources.
Secure Storage β€” encrypt tokens at rest. One store's token compromise is one merchant's
data breach.
Refresh on a calendar, not on a 401 β€” see the warning in step 3. This is the most
important operational rule on this page.
Store tokens per merchant, keyed by store id β€” a refresh replaces the whole token set
for one store only.
Branch on message.code, never on message.description β€” descriptions are localised
(Arabic by default) and are editorial text that can change. The codes are stable.
Handle 429 β€” the API rate-limits per app per store. Respect the Retry-After
response header. See Rate Limiting.

Sample OAuth Clients#

We have developed sample starter apps to help you kick-start your integration:
1.
Laravel App Sample
2.
Node.js + Express App Sample
Modified atΒ 2026-10-19 15:06:52
Previous
Authorization
Next
Public Apps OAuth Requirements
Built with