API / MCP · v2.8.2

Customer Infrastructure API

Passquare connects your product to Apple Wallet and Google Wallet. Issue passes, update them, and send push from one API.

Issue and update Wallet passes from your product

One API for identity, pass state, push, and automation in Apple Wallet and Google Wallet.

Your app / CRM / AIcustomer data + event
→
Passquare APIWallet, push, NFC
→
Customer phoneApple Wallet · Google Wallet
Identitycustomer → wallet → phone → business
Statebalance, membership, ticket, status
Communicationpush, geo, live pass updates
Automationevent → trigger → action

Conceptual call

{
  "phone": "+420000000001",
  "balance": 1250,
  "tier": "Gold"
}

Passquare updates Apple Wallet and Google Wallet, shows the current status, can send a push, apply a segment, and fire a trigger. The customer sees it in Wallet.

MCP server

Connect this server to an AI client: ChatGPT, Claude, Cursor, and others. The agent can find a customer, update the pass, create an offer, and send a push. The private key is in Integration → API in your dashboard.

{
  "mcpServers": {
    "Passquare": {
      "type": "http",
      "url": "https://mcp.passquare.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_PRIVATE_KEY"
      }
    }
  }
}

Your system → Passquare

Create and update Wallet passes when data changes in your CRM, and read data from Passquare. Send app_key, the private key from Integration → API in your dashboard. Test with Postman.

1.1 status

Check the private key and account status.

POST https://core.passquare.com/api/v2/status
Request
{
  "app_key": "private_key"
}
Response
{
  "app": "account_name",
  "balance": 980.00
}

1.2 user_create_or_update

Create or update a customer in Passquare. The phone number is the key and uses E.164. You can also pass custom variables in the payload. template_uuid is in the address bar of the template.

POST https://core.passquare.com/api/v2/crm/user_create_or_update
Request
{
  "app_key": "private_key",
  "name": "name",
  "phone": "customer mobile phone",
  "email": "email address",
  "surname": "surname",
  "middlename": "patronymic",
  "birthday": "date of birth dd.mm.yyyy",
  "discount": "discount percent",
  "bonus": "bonus percent",
  "balance": "bonus amount",
  "card_track": "...",
  "template_uuid": "...",
  "customerId": "customer id in your CRM",
  "link": "link to the pass issue form",
  "sms": "Your card: %link%"
}

To send a personalized install link, pass the form URL in link. In the SMS text, %link% is replaced with that URL.

Response
{
  "success": true,
  "sms_send": true,
  "card": true,
  "card_number": "created card number",
  "card_track": "created card track",
  "card_url": "personalized Apple Wallet link",
  "card_gpay_url": "personalized Google Wallet link",
  "form_url": "personalized form link",
  "user_hash": "hash for form personalization"
}
Create a customer and send SMS
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "phone": "+420000000001",
  "email": "",
  "name": "Joe",
  "surname": "Master",
  "middlename": "Remaster",
  "birthday": "11.11.1980",
  "discount": 0,
  "bonus": 3.50,
  "balance": 100,
  "link": "https://form.passquare.com/00000000-0000-0000-0000-000000000000",
  "sms": "Your card: %link%"
}
SMS example
Your card: https://form.passquare.com/00000000-0000-0000-0000/?hash=2f10171a33f66f3bc425335690ec880c
Update balance

If the template has a push bound to balance change, the customer also sees a lock-screen message. To add or deduct an amount, use balance/add and balance/deduct.

{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "phone": "+420000000001",
  "balance": 120
}
Personalized Wallet push
When sending a push, do not change variables that notifications are bound to in the template. If you send a push and change such a variable at the same time, the system will send a “pass updated” message instead.
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "phone": "420000000001",
  "push": "Your order is ready for pickup!"
}
Web push

Requires a connected web push app from the Marketplace.

{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "phone": "+420000000001",
  "send_webpush": "Your order is ready for pickup!"
}

1.3 read_customer

Get customer data by phone or card number. Phone numbers use E.164.

POST https://core.passquare.com/api/v2/crm/read_customer
Request: use phone or card
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "phone": "",
  "card": "",
  "invites": true,
  "installs": true
}
Response
{
  "customer": {
    "phone": "+420000000001",
    "email": "",
    "name": "Joe",
    "surname": "Master",
    "middlename": "Remaster",
    "birthday": "11.11.1980",
    "cardNumbers": ["120"],
    "cardTracks": [{"card": "120", "track": "78374598987"}],
    "cardInstalls": [{"card": "120", "install": true}],
    "discount": 4.5,
    "bonus": 0,
    "balance": 0,
    "template_uuid": "...",
    "remoteId": "6326",
    "invitedBy": "+420000000000",
    "invites": ["+420000000011", "+420000000012"]
  }
}

1.4 read_customers

List customers by registration date.

POST https://core.passquare.com/api/v2/crm/read_customers
Request
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "start_date": "01.01.2020",
  "end_date": "31.12.2020 23:59:59",
  "installed": true,
  "offset": 0
}
  • If installed is omitted, the method returns all customers.
  • If true: customers with an installed pass.
  • If false: customers without an installed pass.
  • Returns the first 100 customers. Use offset for the next page.
Response
{
  "customers": ["+420000000011", "+420000000012"]
}

1.5 push/create

Create a push campaign for the whole base or a segment. Type can be push or webpush. Web push needs a Marketplace app. After creating the campaign, send it with push/send. For a single customer push, use user_create_or_update. segment_uuid is in the address bar of the segment.

POST https://core.passquare.com/api/v2/crm/push/create
Request
{
  "app_key": "",
  "message": "",
  "type": "",
  "name": "",
  "segment_uuid": ""
}
Response
{
  "result": {
    "name": "Push#0000",
    "uuid": "00000000-0000-0000-0000-000000000000",
    "message": "Test push!"
  }
}

1.6 push/send

Run a push campaign. push_uuid is in the address bar of the campaign, or take it from the push/create response.

POST https://core.passquare.com/api/v2/crm/push/send
Request
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "push_uuid": "00000000-0000-0000-0000-000000000000"
}

1.7 event/send

Send an event for a customer. app_key, event and one customer identifier are required: phone, card or remoteId. The event key is created in the Events section of the account. value is an optional string of up to 100 characters. Phone is in E.164 format.

POST https://core.passquare.com/api/v2/crm/event/send
Request with phone
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "phone": "+420000000001",
  "event": "site_visit",
  "value": "promo"
}
Request with card
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "card": "1000123456",
  "event": "site_visit",
  "value": "promo"
}
Request with remoteId
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "remoteId": "crm-42",
  "event": "site_visit",
  "value": "promo"
}
Response
{
  "success": true
}

1.8 balance/add

Add to a customer's bonus balance. Same operation as Add on the client card. app_key, sum and one customer identifier are required: phone, card or remoteId. sum is a positive amount added to the current balance. On the built-in customer base, Passquare changes the balance itself. If an external CRM is connected, Passquare sends it the addBalance hook, the same way the Add button does, and then updates the pass from the CRM. Phone is in E.164 format. If the template has a push bound to balance change, the customer also sees a lock-screen message.

POST https://core.passquare.com/api/v2/crm/balance/add
Request with phone
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "phone": "+420000000001",
  "sum": 50.00
}
Request with card
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "card": "100099",
  "sum": 50.00
}
Request with remoteId
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "remoteId": "crm-42",
  "sum": 50.00
}
Response
{
  "success": true,
  "balance": 150.00
}

1.9 balance/deduct

Deduct a customer's bonus balance. Same operation as Deduct on the client card. app_key, sum and one customer identifier are required: phone, card or remoteId. sum is a positive amount subtracted from the current balance. On the built-in customer base, Passquare changes the balance itself. If an external CRM is connected, Passquare sends it the addBalance hook, the same way the Deduct button does, and then updates the pass from the CRM. Phone is in E.164 format. If the template has a push bound to balance change, the customer also sees a lock-screen message.

POST https://core.passquare.com/api/v2/crm/balance/deduct
Request with phone
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "phone": "+420000000001",
  "sum": 50.00
}
Request with card
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "card": "100099",
  "sum": 50.00
}
Request with remoteId
{
  "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "remoteId": "crm-42",
  "sum": 50.00
}
Response
{
  "success": true,
  "balance": 50.00
}

Passquare → your system

When a customer receives a Wallet pass, Passquare sends a hook to the HTTPS URL in your integration settings. Handle it and store the customer in your database. When balance or discount changes on your side, send a hook back: Passquare updates the pass and can send a push.

Auth: HTTP Basic or crm_key. For crm_key, put it in the password field and leave login empty. Headers: X-organization-id, X-program-id, X-wallet-id. You can also allowlist IP 164.90.200.81. For debugging use webhook.site.

2.1 createCustomer

Register a customer pass. Look up the customer by phone (E.164). If missing, create them and a card, return customerId. If they exist, update, add a card (or replace if your CRM is one-card), return customerId. Card numbers are issued by Passquare; set the start of a free range in integration settings.

POST HTTPS webhook URL
{
  "crm_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "method": "createCustomer",
  "customer": {
    "name": "Joe",
    "surname": "Master",
    "middlename": "Remaster",
    "email": "",
    "phone": "+420000000001",
    "birthday": "1980-01-25",
    "cardNumbers": ["120"],
    "cardTracks": [{"card": "120", "track": "7862374687"}],
    "extra": {
      "gender": "male",
      "promo": "BBBBB"
    },
    "balance": 300.00,
    "bonus": 10.00,
    "discount": 25.00,
    "promo": "AAAAA",
    "user_hash": "a4f8c9d3e6527b1acd07e8f4b6a9d2c3",
    "referCustomerPhone": "+420000000002"
  }
}

Required response: customerId: unique customer id in your CRM.

HTTP 200
{"customerId": "6d2845ff-0a07-11e7-25df-d8d18565926f"}
HTTP 400
{"error": "Detailed error description..."}

2.2 readBalance

Balance lookup for a manual refresh of bonuses and discount on the pass.

POST HTTPS webhook URL
Request
{
  "crm_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "method": "readBalance",
  "customer": {
    "phone": "+420000000001",
    "cardNumbers": ["120"]
  }
}

Return balance / bonus / discount for the customer identified by phone and card number.

Response
{
  "success": true,
  "bonus": 12.5,
  "balance": 5,
  "discount": 17.88
}

2.3 addBalance

Hook to credit and write off bonuses.

POST HTTPS webhook URL
Request
{
  "crm_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "method": "addBalance",
  "customer": {
    "phone": "+420000000001",
    "cardNumbers": ["120"],
    "sum": 50.00,
    "transactionId": "id/guid",
    "lifetime": 14
  }
}

Credit the customer identified by phone and card number. For a write-off the hook sends a negative sum, for example -50.00. If lifetime is passed, that credit expires after that many days (24h).

Response
{
  "success": true
}

2.4 setPrivileges

Hook to set the bonus percent and the discount percent. These are percentage rates, not the bonus balance.

POST HTTPS webhook URL
Request
{
  "crm_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "method": "setPrivileges",
  "customer": {
    "phone": "+420000000001",
    "cardNumbers": ["120"],
    "bonus": 10.00,
    "discount": 5.00
  }
}

Store the new rates for the customer: bonus is the bonus percent, discount is the discount percent. The hook sends only the fields that changed: bonus alone, discount alone, or both at once. Leave a field unchanged when it is absent from the request.

bonus only
{
  "crm_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "method": "setPrivileges",
  "customer": {
    "phone": "+420000000001",
    "cardNumbers": ["120"],
    "bonus": 10.00
  }
}
discount only
{
  "crm_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "method": "setPrivileges",
  "customer": {
    "phone": "+420000000001",
    "cardNumbers": ["120"],
    "discount": 5.00
  }
}
Response
{
  "success": true
}

Notes

Appendix A. curl
curl -X POST https://core.passquare.com/api/v2/crm/user_create_or_update \
  -H "Content-Type: application/json" \
  -d '{
    "app_key": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "phone": "+420000000001",
    "email": "",
    "name": "Joe",
    "surname": "Master",
    "middlename": "Remaster",
    "birthday": "03.05.1980",
    "discount": 0,
    "bonus": 5,
    "balance": 200
  }'
Appendix B. PHP
<?php
$url = 'https://core.passquare.com/api/v2/crm/user_create_or_update';
$post = [
  'app_key' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
  'phone' => '+420000000001',
  'email' => '',
  'name' => 'Joe',
  'surname' => 'Master',
  'middlename' => 'Remaster',
  'birthday' => '03.05.1980',
  'discount' => 0,
  'bonus' => 4.5,
  'balance' => 100
];
$data_string = json_encode($post);
$ch = curl_init();
curl_setopt_array($ch, [
  CURLOPT_TIMEOUT => 30,
  CURLOPT_POST => 1,
  CURLOPT_URL => $url,
  CURLOPT_RETURNTRANSFER => 1,
  CURLOPT_SSL_VERIFYPEER => true,
  CURLOPT_POSTFIELDS => $data_string,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    'Content-Length: '.strlen($data_string)
  ]
]);
echo curl_exec($ch);
?>
  • Rate limits: Basic 1 rps / 60 per hour; Advanced 1 rps / 600 per hour; Expert and Exclusive 1 rps / 3600 per hour. All requests from your system count. Limits can be raised via support.
  • Examples may use JSON5 comments. Real JSON requests cannot contain comments.
  • On error, send support the request and response logs.
  • To send enrollments into your CRM, implement the Passquare → your system methods.
  • Incoming hooks: webhook.site. Outgoing calls: Postman.

Get started free

Try Passquare — it’s free & easy.

Create an account, set up your signup form, design your cards, issue a few wallet passes, and send your first push notifications.

Sign up for free
Wallet card signup form