Build with the
JadCoins Customer API
Integrate loyalty points, wallets, and JadCoins into your POS system or application. Everything you need to get started.
Introduction
The JadCoins Integration API allows external businesses and POS systems to integrate with the JadCoins loyalty platform. Through this API, partner companies can manage customers, award loyalty points based on purchases, manage wallets, and process JadCoins payments.
Key Features
Customer Management — Register and manage customer accounts linked to your business.
Points System — Award loyalty points automatically based on purchase amounts with configurable rules.
Auto-Redemption — Points are automatically converted to wallet balance when they reach the threshold.
Wallet System — Customers can use their wallet balance as payment at your business.
JadCoins — A cross-platform coin system that customers can spend across integrated businesses.
SMS Notifications — Automatic SMS for welcome, points earned, and wallet used events.
Authentication
All API requests must include an API key in the request header. Each integrated company receives a unique API key.
Required Header
X-Api-Key: your-api-key-here
Authentication Errors
| Status | Error | Description |
|---|---|---|
401 | Missing X-Api-Key header | The header was not provided in the request. |
401 | Invalid API key | The provided API key does not match any registered company. |
404 | Company not found | The API key is valid but the associated company was not found. |
Base URL & General Information
Base URL
There are two path bases. API-key endpoints live under /api/integration; the two public endpoints live directly under /api (no /integration segment).
https://your-domain.com/api/integration
https://your-domain.com/api
your-domain.com is a placeholder. The repository only configures APP_URL=http://localhost; no production domain is committed. Replace it with your actual host.
Request / Response Format
All requests and responses use application/json. The envelope comes from the ApiResponses trait and has exactly two top-level keys per branch — success returns { value, data } (no msg), a manual error returns { value, msg } (no data). value is true only for HTTP 200/201/202.
Validation Errors (422) — two shapes
Validation failures do not share one shape. Endpoints backed by a FormRequest (check-or-create, earn points, use-wallet, verify company by code) return a Laravel-style body with success/message/errors and no value key. Endpoints using an inline validator (update-profile, both jad-coins endpoints) return the standard { value:false, msg:{…} } envelope where msg is the errors object.
phone_code parameter accepts the + prefix or not (e.g. "+972" or "972") only on the endpoints that normalize it: update-profile, get balance, and both jad-coins endpoints. Exact match (no normalization): check-or-create, points/earn, and use-wallet compare phone_code exactly as sent against the stored code — send it with the +, otherwise the lookup fails with 404 "Customer not found".
API Endpoints
Verify Company
Verify that your API key is valid and retrieve your company details and loyalty configuration.
Parameters
No additional parameters required. Authentication is handled via the X-Api-Key header.
Check or Create Customer
Find an existing customer by phone number or create a new one. The customer will be linked to your company automatically. A welcome SMS is sent to new customers.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code (e.g., "+972") |
name | string | Yes | Customer full name |
email | string | No | Customer email address |
national | string | No | National ID or nationality (nullable|string) |
birth_date | date | No | Date of birth (YYYY-MM-DD). When present, the new customer is created with is_profile_complete = true. |
city_id | integer | No | City ID (nullable|exists:cities,id) |
is_new_customer is currently inverted in the code (!$customer->wasRecentlyCreated): a customer that was just created returns is_new_customer: false, while an already-existing customer returns true. Treat this flag with care until it is fixed in the API.
Get Customer Balance
Retrieve the current point balance, wallet balance, and JadCoins balance for a customer.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code |
GET /api/integration/customer/balance?phone=0509124719&phone_code=+972 X-Api-Key: your-api-key-here
403 { value:false, msg:"Loyalty program is disabled" } before any customer lookup. The success response includes a nested city object ({ id, name, name_en, name_he }) or null when the customer has no city set. jad_coins reflects the customer's total coins across all operators.
Update Customer Profile
Update a customer's profile. Required before the customer can use their wallet balance. The birth_date field is mandatory to complete the profile.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code |
name | string | Yes | Customer full name |
email | string | Yes | Customer email address |
national | string | No | National ID or nationality (nullable|string|max:255) |
birth_date | date | Yes | Date of birth (YYYY-MM-DD) |
city_id | integer | No | City ID (nullable|exists:cities,id) |
is_profile_complete = true. The customer must already exist and be linked to your company. Validation uses an inline validator, so a 422 uses the { value:false, msg:{…} } shape (not the FormRequest shape).
{ "value": false, "msg": "Customer not found" }
{ "value": false, "msg": "Customer is not linked to this company" }
{ "value": false, "msg": "Loyalty program is disabled" }
Earn Points from Purchase
Award loyalty points based on a purchase amount. If the customer's point balance reaches the minimum redemption threshold, points are automatically converted to wallet balance.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code |
purchase_amount | number | Yes | The total purchase amount (required|numeric|min:0) |
order_id | string | Yes | Required by validation (required|string). Note: this value is validated but not stored on the transaction. |
reference | string | No | Not validated, but this is the value actually saved as the transaction reference. Omit → stored as null. |
msg for the 400 errors is an object { points_earned, message }, not a string. A purchase above max_purchase_amount is rejected with a 400 here (it is not capped). If the customer cannot be found, this endpoint returns 403 "Customer not found" (not 404). Points are floored to a whole number before crediting.
Use Wallet Balance
Deduct from the customer's wallet as payment. Profile must be complete. If allow_points_on_redemption is enabled, points are also earned.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code |
amount | number | Yes | Amount to deduct from wallet (required|numeric|min:0.01) |
purchase_amount | number | No | Total purchase amount used to earn points (nullable|numeric|min:0). Only relevant when allow_points_on_redemption is enabled. |
reference | string | No | Your order/invoice reference (nullable|string|max:255) |
earned_points is 0 unless allow_points_on_redemption is enabled for the company; when enabled, points are earned from purchase_amount and the auto-redeem loop may also run. Other errors: 403 "Please complete your profile firstly" (profile incomplete), 404 "Customer not found", 403 "Loyalty program is disabled". Validation failures use the FormRequest 422 shape.
Check JadCoins Balance
Check a customer's JadCoins balance. JadCoins are a cross-platform currency from operators.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customer_id | integer | No | Customer ID (alternative to phone) |
phone | string | No | Customer phone number |
phone_code | string | No | Country phone code |
customer_id OR both phone and phone_code. customer_id takes precedence. Unlike jad-coins/use, this endpoint does not return a 422 for missing identifiers — supplying none simply resolves to 404 Customer not found. (A non-existent customer_id still fails the exists:customers,id rule and returns 422.) Only wallets with a positive balance appear in wallets_detail.
Use JadCoins
Deduct JadCoins as payment. Uses FIFO (oldest wallet first). A settlement transaction is logged automatically.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customer_id | integer | No | Customer ID (alternative to phone) |
phone | string | No | Customer phone number |
phone_code | string | No | Country phone code |
amount | number | Yes | Amount of JadCoins to spend |
reference | string | No | Your order/invoice reference |
Public Endpoints (No API Key)
VerifyIntegrationApiKey middleware and require no X-Api-Key. The company is identified by a unique_code sent in the request. Anyone who knows a company's unique_code can call them — treat that value as semi-sensitive. Their base path is /api (no /integration segment).
Verify Company (public)
Look up a company and its loyalty configuration by its public unique_code. Same response body as the API-key variant.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
unique_code | string | Yes | The company's public unique code (required|string|max:255) |
GET /api/company/check?unique_code=CRISPY01
Check or Create Customer (public)
Find or create a customer and link them to the company identified by company_unique_code. A welcome SMS is sent to newly-linked customers.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
company_unique_code | string | Yes | Identifies the company (required|string|exists:companies,unique_code) |
phone | string | Yes | Customer phone number |
phone_code | string | Yes | Country phone code (e.g. "+972") |
name | string | Yes | Customer full name (max:255) |
email | string | No | Customer email (nullable|email) |
national | string | No | National ID / nationality |
birth_date | date | No | Date of birth (YYYY-MM-DD) |
city_id | integer | No | City ID (nullable|exists:cities,id) |
accept_terms | boolean | No | Terms acceptance flag (nullable|boolean) |
is_new_customer inversion applies here (true = existing customer). This route is the public sibling of /integration/customer/check-or-create; the API-key variant has no company_unique_code or accept_terms fields.
Business Logic Reference
Points Calculation
| Type | Calculation | Example |
|---|---|---|
percent | purchase_amount × percentage_points / 100 | 150 × 10% = 15 points |
fixed | Fixed amount per transaction | 5 points per purchase |
none | No points awarded | N/A |
/points/earn: a purchase below min_purchase_amount or above max_purchase_amount is rejected with a 400 (no points, not capped). On the /use-wallet earn path: below-min earns 0 and above-max is capped to max_purchase_amount. Rounding differs: /points/earn floors earned points to a whole number, whereas the /use-wallet path keeps percent-based points at 2 decimals (rounded, not floored). points_type that is neither fixed nor percent yields 0.
Auto-Redemption
When points reach min_redemption_points, the system automatically:
1. Deducts points in multiples of the threshold.
2. Calculates wallet value: redeemed_points × point_value.
3. Applies redeem cap if configured.
4. Adds the amount to the customer's wallet.
5. Repeats until remaining points are below the threshold.
Redeem Cap
| Cap Type | Behavior | Example |
|---|---|---|
none | No limit | 100 pts × 1.0 = ₪100 |
fixed | Max fixed amount | Cap 80: 100 pts × 1.0 = ₪80 (capped) |
percent | % of wallet value | Cap 20%: 100 × 1.0 × 20% = ₪20 |
Points Expiry Policy
| Policy | Expiration Date |
|---|---|
week | End of current week (Friday) |
month | End of current month |
quarter | End of current quarter |
half_year | Jun 30 or Dec 31 |
year | Dec 31 |
none | Never expires |
Wallet Usage Rules
Customers must have is_profile_complete = true to use their wallet, otherwise /use-wallet returns 403 "Please complete your profile firstly".
In practice is_profile_complete is set to true when a customer is created with a birth_date, or after a successful update-profile (which validates name + email + birth_date). It is not independently enforced as a three-field rule at creation time.
If allow_points_on_redemption is enabled, customers also earn points (from purchase_amount) when paying with their wallet, and the auto-redeem loop may run.
JadCoins (Cross-Platform Currency)
Not tied to a specific company — can be spent at any integrated business.
Distributed by operators — not earned from purchases.
Settlement tracking — spending triggers a settlement transaction.
FIFO deduction — oldest wallet balances are used first.
Typical Integration Flow
The recommended sequence for a typical POS integration:
Verify Company Setup
Call GET /integration/company/check on startup to verify your API key and retrieve loyalty config.
Identify Customer
Call POST /integration/customer/check-or-create with the customer's phone number.
Check Balance
Call GET /integration/customer/balance to display points, wallet, and JadCoins to the cashier.
Process Purchase
Call POST /integration/points/earn with purchase_amount and a (required) order_id. Points are awarded and auto-redeemed if applicable.
Apply Payment (Optional)
Use POST /integration/use-wallet for wallet payment, or POST /integration/jad-coins/use for JadCoins.
Update Profile (If Needed)
If profile is incomplete, call POST /integration/customer/update-profile with the required details.
Error Codes Reference
| Code | Meaning | Common Causes |
|---|---|---|
200 | Success | Request processed. Envelope { value:true, data }. |
400 | Bad Request | /points/earn only: purchase below min_purchase_amount or above max_purchase_amount. msg is an object { points_earned, message }. |
401 | Unauthorized | Missing X-Api-Key header, or invalid API key (API-key endpoints only). |
403 | Forbidden | Loyalty disabled; profile incomplete (use-wallet); customer not linked (update-profile). Note: /points/earn also returns 403 — not 404 — when the customer is not found. |
404 | Not Found | Customer not found (balance / update-profile / use-wallet / jad-coins), or company not found (public check & API-key middleware). |
422 | Validation Error | Two shapes: FormRequest → { success, message, errors }; inline validator → { value:false, msg:{…} }. Also manual strings: "Invalid phone code", "Insufficient wallet balance", "Insufficient jad coins balance. Available: N", "Provide either customer_id or both phone and phone_code". |
500 | Server Error | Caught exception inside a transaction → { value:false, msg:"Failed to …" / "Integration failed: …" }. |
Build with the
JadCoins Employee API
Expose the full set of employee (POS-side) operations to your external system: points, wallet, customers, milestones, JadCoins, and messaging — authenticated by your company API key plus an employee_id.
Introduction
The Employee Integration API mirrors what a company employee can do inside the JadCoins app, exposed to your own POS / back-office. It is a separate surface from the Customer API and lives under /api/integration/employee. Every write is attributed to a specific employee for auditing.
Key Features
Points — earn from purchases (with auto-redemption), manual redeem, transaction history, and reversal.
Wallet — pay from wallet balance (optionally earning points on the same purchase), history, and reversal.
Customers — check-or-create & link to your company, search, list, and mark the birthday gift as used.
Reward Milestones — read a customer's gift ladder and claim a gift on their behalf.
JadCoins — search by the customer's code, check balance, and spend.
Messaging — resend the terms SMS and read the company's 019 SMS balance.
Authentication
Two layers, checked in order. Layer 1 is the same company API key as the Customer API (X-Api-Key header). Layer 2 is an employee_id that must belong to that company — sent in every request (query for GET, body for POST).
Required Header
X-Api-Key: your-api-key-here
Required in every request
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | ID of the employee performing the action. Must belong to the company that owns the API key. Sent as a query param on GET and in the body on POST. |
employee_id resolves the employee within that company and stamps every points/wallet transaction with employee_id. Any active employee of the company is accepted (no PIN needed on this surface).
Authentication error chain
| Status | When | Body |
|---|---|---|
401 | Missing/invalid X-Api-Key | { value:false, msg:"Missing X-Api-Key header" } / "Invalid API key" |
422 | Key OK but no employee_id | { value:false, msg:"Missing employee_id" } |
403 | employee_id not in this company | { value:false, msg:"Employee not found in this company" } |
Base URL & General Information
Base URL
https://your-domain.com/api/integration/employee
your-domain.com is a placeholder — replace with your actual host. All 18 endpoints below are relative to this base and require the API key + employee_id.
Method & Delete Convention
This surface is GET / POST only. Reads and deletes use GET; creates and mutations use POST. A delete is expressed as GET .../delete and reverses the transaction's effect on the balance.
Response Envelope
Identical to the Customer API — success is { value:true, data }, a manual error is { value:false, msg }. FormRequest validation failures (earn / redeem / wallet-use / check-or-create / jad-use) return the Laravel shape { success:false, message, errors } with no value key.
customer_id or phone + phone_code. phone_code is matched exactly against the stored code — send it with the + (e.g. "+972").
Points
Points Transactions
Paginated point-transaction history for your company, optionally filtered by customer or type.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
customer_id | integer | No | Filter by customer |
type | string | No | Filter by type (EARN, REDEEM, EXPIRE) |
Earn Points from Purchase
Award points from a purchase amount. When the balance reaches min_redemption_points, points auto-convert to wallet balance. A points-earned SMS is sent (respecting the company config).
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
customer_id | integer | No* | Customer ID (or use phone + phone_code) |
phone | string | No* | Customer phone (with phone_code) |
phone_code | string | No* | e.g. "+972" |
purchase_amount | number | Yes | required|numeric|min:0 |
reference | string | No | Saved as the transaction reference |
* Provide either customer_id or phone + phone_code.
points_earned is 0 and the endpoint returns 422 with the reason. 404 "Customer not found" if the customer cannot be resolved.Redeem Points (manual)
Manually convert points to wallet cash. Requires enough balance and at least min_redemption_points.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
customer_id / phone+phone_code | — | Yes | Customer target (one of) |
points | number | Yes | required|numeric|min:1 |
reference | string | No | Transaction reference |
422 "Insufficient points" or "Minimum redemption is N points". The wallet is credited by points × point_value (subject to the redeem cap).Delete Point Transaction
Delete a point transaction and reverse its effect on the balance (EARN subtracts, REDEEM/EXPIRE add back). Scoped to your company.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id (path) | integer | Yes | Point transaction ID |
employee_id (query) | integer | Yes | Acting employee |
{ "value": false, "msg": "Not Found" }Wallet
Wallet Transactions
Paginated wallet-transaction history for your company, optionally filtered by customer or type.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
customer_id | integer | No | Filter by customer |
type | string | No | ADD, SPEND, REFUND, WITHDRAW |
Use Wallet Balance
Deduct from the customer's wallet as payment (SPEND). If allow_points_on_redemption is enabled, points are also earned on (purchase_amount − amount) and may auto-redeem.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
customer_id / phone+phone_code | — | Yes | Customer target (one of) |
amount | number | Yes | required|numeric|min:0.01 — amount to deduct |
purchase_amount | number | No | Total purchase (for points-on-redemption) |
reference | string | No | Order/invoice reference |
earned_points is 0 unless allow_points_on_redemption is enabled. 404 "Customer not found", 422 "Insufficient wallet balance".Delete Wallet Transaction
Delete a wallet transaction and reverse its effect (ADD/REFUND subtract, SPEND/WITHDRAW add back). Scoped to your company.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id (path) | integer | Yes | Wallet transaction ID |
employee_id (query) | integer | Yes | Acting employee |
{ "value": false, "msg": "Not Found" }Customers
Check or Create Customer
Find a customer by phone + phone_code; if missing, create them; either way, link to your company. Idempotent — a welcome SMS is sent when the customer is newly linked. Wallets are created for your company.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
phone | string | Yes | Customer phone (max:20) |
phone_code | string | Yes | e.g. "+972" (max:10) |
name | string | Yes | Customer full name (max:255) |
email | string | No | nullable|email |
national | string | No | National ID / nationality |
birth_date | date | No | YYYY-MM-DD (sets is_profile_complete) |
city_id | integer | No | nullable|exists:cities,id |
is_new_customer = the Customer record was just created. newly_linked = an existing customer was linked to your company on this call (welcome SMS sent). 422 "Invalid phone_code" if phone_code is unknown.Search Customer
Find a single customer of your company by phone (partial match).
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
phone | string | Yes | Phone to search (partial) |
List Customers
Paginated list of your company's customers, filterable by name or phone.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
name | string | No | Filter by name (partial) |
phone | string | No | Filter by phone (partial) |
Mark Birthday Gift Used
Mark the customer's birthday gift as used for the current period. Requires the customer to have a birth date, be inside the birthday window, and not have used it yet.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
customer_id | integer | Yes | Customer of your company |
Customer Milestones (gift ladder)
The customer's reward-milestone status: the company mode, the gift budget available, and every gift with its 3-language name, icon, status, claim count, remaining, and progress.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customerId (path) | integer | Yes | Customer of your company |
employee_id (query) | integer | Yes | Acting employee |
mode is spend_to_earn (free, budget-based) or redeem_wallet (deducts from wallet). status per gift is takeable, close, or not_reached.Claim Milestone (take gift)
Claim a gift on the customer's behalf. Atomic — validates availability/budget and records the claim under this employee.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customerId (path) | integer | Yes | Customer of your company |
milestoneId (path) | integer | Yes | Gift/milestone ID |
employee_id (body) | integer | Yes | Acting employee |
422 when the gift is not available or the budget/wallet is insufficient (message from the domain rule). 404 if the customer or milestone is not found for your company.JadCoins
Search by Code
Resolve the customer from the short code shown in their app, and return their JadCoins wallets and total balance.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
code | string | Yes | Customer's code (min:8|max:10) |
Check JadCoins Balance
Check a customer's JadCoins balance by customer_id or phone.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
customer_id / phone+phone_code | — | Yes | Customer target (one of) |
Use JadCoins
Spend JadCoins as payment. FIFO deduction (oldest wallet first); a settlement transaction is logged.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
customer_id / phone+phone_code | — | Yes | Customer target (one of) |
amount | number | Yes | required|numeric|min:0.01 |
reference | string | No | Order/invoice reference |
Misc
Resend Terms SMS
Resend the terms-acceptance SMS to a customer of your company (respects the company SMS config).
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
customerId (path) | integer | Yes | Customer of your company |
employee_id (body) | integer | Yes | Acting employee |
{ "value": false, "msg": "Not Found" }SMS Balance
Read your company's 019 SMS credit balance. This calls the 019 provider (read-only) and returns the matched sub-account balance.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
employee_id | integer | Yes | Acting employee |
404 if the company has no SMS configuration, 422 if it's incomplete (missing username), 500 if the provider call fails. When the username isn't matched, balance is null with status:"not_found".Error Codes Reference
| Code | Meaning | Common Causes |
|---|---|---|
200 | Success | Envelope { value:true, data }. |
401 | Unauthorized | Missing or invalid X-Api-Key. |
403 | Forbidden | employee_id does not belong to the company ("Employee not found in this company"). |
404 | Not Found | Customer / transaction / milestone not found for your company. |
422 | Validation / Rule | Missing employee_id; FormRequest errors { success, message, errors }; "Insufficient wallet balance"; "Insufficient jad coins balance. Available: N"; "Minimum redemption is N points"; milestone not available. |
500 | Server Error | Caught exception inside a transaction → { value:false, msg:"Failed to …" }. |