Introduction
Look up the customer behind a Just-tap tag.
A customer taps a Just-tap tag at your terminal. A customer query tells you who that customer is, and which mobile-money numbers are on the tag.
Send the tag with your merchant, terminal, reference, and amount. You can list the queries you have already sent, and later report whether the terminal transaction was successful or failed.
Environments
The paths below are the same on both hosts. Use the sandbox while you integrate. Use production for live terminals. The API reference lets you switch host when you try a request.
| Environment | Host |
|---|---|
| Sandbox | https://api-uat.cards.justtap.io |
| Production | https://api.cards.justtap.io |
Authentication
Send your API key in the x-api-key header on every request. Just-tap issues the key. The key identifies your organization, so you do not send a partner id in the body.
POST /api/v1/partners/customer-queries
x-api-key: <your-api-key>
Content-Type: application/json
A missing, invalid, revoked, or expired key returns 401. A key that cannot run customer queries returns 403.
Submit a customer query
POST /api/v1/partners/customer-queries
tagId is the tag the customer tapped. referenceId is your id for this query, and it has to be unique. merchantId is your id for the shop. The first time we see that id for your organization, we store merchantName. Later queries for the same id keep that name. Leave currency out to use ZMW. Send the mobile money provider’s externalId when you report the terminal result.
{
"merchantId": "YKrpx3FrpVHWjmIwpqMt",
"merchantName": "Young Phiroz",
"terminalId": "D1K0600000849",
"referenceId": "8244c279-d76c-4e30-ad3b-9efdb12ca692",
"amount": 10,
"tagId": "VZ9T7GM1EYV5MZ"
}
A successful request returns 201. The query is inside data, with the customer’s name and every mobile-money number on the tag. Just-tap adds a service charge of 1 kwacha.
{
"data": {
"id": "b5d746b3-d379-4900-b392-d5045abfb22c",
"partner": {
"partnerId": "edfa86b6-411e-4e66-a681-0cc61abba40e",
"partnerName": "Your Organization"
},
"customer": {
"firstName": "Jane",
"lastName": "Mwansa"
},
"tag": {
"tagId": "VZ9T7GM1EYV5MZ",
"tagNumber": "TAG-000123",
"mobileNumbers": [
{
"operator": "airtel_money",
"mobileNumber": "260970371467",
"status": "active"
}
],
"status": "active"
},
"transaction": {
"merchantId": "YKrpx3FrpVHWjmIwpqMt",
"merchantName": "Young Phiroz",
"terminalId": "D1K0600000849",
"referenceId": "8244c279-d76c-4e30-ad3b-9efdb12ca692",
"externalId": null,
"currency": "ZMW",
"amount": 10,
"serviceCharge": 1,
"totalAmount": 11,
"status": "pending"
},
"createdAt": "2025-04-29T10:00:00.000Z",
"updatedAt": "2025-04-29T10:00:00.000Z"
}
}
The tag must exist, be active, and have at least one mobile number. Sending a referenceId you have already used returns 409.
List your queries
GET /api/v1/partners/customer-queries
This returns the queries submitted with your API key. page starts at 1. perPage defaults to 25 and cannot be higher than 100. The response body is { data, metadata }.
Each item is shorter than the record you get when you submit a query. The customer is identified by tag id and mobile number, not by name.
Report the terminal result
When the terminal finishes the transaction, tell us how it ended. Send successful or failed, the mobile money provider’s externalId, and the query id, your referenceId, or both when they refer to the same query.
The query starts as pending. A later report replaces that status and stores the provider id. Sending the same status and provider id again returns the current record. A query that belongs to another organization returns 404.
POST /api/v1/partners/customer-queries/status
{
"referenceId": "8244c279-d76c-4e30-ad3b-9efdb12ca692",
"externalId": "MM984221",
"status": "successful"
}
A 200 response is the same { data } record you get when you submit a query, with transaction.status updated.
When something goes wrong
Responses are JSON. Timestamps are ISO 8601.
A failed request looks like this:
{
"error": "E_ALREADY_EXISTS",
"message": "A customer query with reference 8244c279-d76c-4e30-ad3b-9efdb12ca692 already exists"
}
If the request itself is invalid, the status is 422 and the body also includes errors. Each entry has field, rule, and message.