ShamCash API
HTTP API for ShamCash accounts that users link on shamcash-api.com. A user registers on the platform, attaches one or more ShamCash accounts to their profile, then uses this API to list those accounts, inspect subscription state, read balances, and query incoming transactions.
Base URL: https://api.shamcash-api.com/v1
All paths below are relative to that base URL.
Authentication
Every request must include a valid API token issued from your platform dashboard.
Header
Authorization: Bearer <api_token>
Tokens are opaque strings. Treat them as secrets; do not embed them in client-side web code or public repositories.
If the token is missing, invalid, or revoked, the API returns status: "error" with an appropriate code and a human-readable message (see Response envelope).
Conventions
Versioning
The v1 path segment is the current major version. Incompatible changes will be introduced under v2, v3, and so on.
Content type
Responses use application/json; charset=utf-8. Request bodies (if added later) should use the same type unless documented otherwise.
Time zones
For /transactions query parameters, start_at and end_at are interpreted in Asia/Damascus unless you pass a full ISO 8601 value with an explicit offset.
Transaction objects return occurred_at as an ISO 8601 timestamp with offset (for example 2026-04-16T01:22:21+03:00).
Account lifecycle
Each item under /accounts is a ShamCash account the user linked on the platform. It has a status (active | inactive) and optional subscription_expires_at describing when API access for that link ends. If the user calls /balances or /transactions when the link is inactive, there is no subscription, or the subscription period has ended, the API returns SUBSCRIPTION_UNAVAILABLE (see Error codes).
Response envelope
Every response uses the same top-level shape:
{
"status": "success",
"code": "SUCCESS",
"message": "Accounts retrieved successfully.",
"data": {}
}
| Field | Type | Description |
|---|---|---|
status | string | "success" or "error" |
code | string | Machine-readable outcome (see Error codes) |
message | string | Human-readable summary: on success, a short confirmation; on error, what went wrong and what the user can do next |
data | mixed | Payload on success; on error often null or [] depending on endpoint |
Success
statusis"success".codeis"SUCCESS".messagebriefly describes the outcome (for example "Balances retrieved successfully.").datafollows the schema described for each endpoint.
Error
statusis"error".codeis one of the values in Error codes.messagealways explains the failure in plain language (validation hint, auth hint, subscription hint, etc.).datais typicallynullor an empty array. Clients should usecodefor branching andmessagefor display or logging.
Error codes
code | Typical HTTP | Meaning |
|---|---|---|
SUCCESS | 200 | Request completed successfully. |
VALIDATION_ERROR | 400 | Malformed or conflicting query parameters (e.g. invalid date format, invalid coin_id). |
AUTH_MISSING | 401 | No Authorization header or empty token. |
AUTH_INVALID | 401 | Token unknown, expired, or revoked. |
FORBIDDEN | 403 | Token valid but not allowed to perform this action. |
NOT_FOUND | 404 | Resource not found (e.g. unknown account_id for this user). |
SUBSCRIPTION_UNAVAILABLE | 403 | This operation is not allowed because the account has no active subscription, the subscription period has ended, the ShamCash link is inactive, or subscription data is missing. The exact situation is described in message. |
RATE_LIMIT_EXCEEDED | 429 | Too many requests; retry after the period indicated by Retry-After when present. |
FETCH_FAILED | 502 | Upstream or internal data fetch failed; safe to retry with backoff. |
INTERNAL_ERROR | 500 | Unexpected server error. |
Exact HTTP status for a given code may be tuned per deployment; use status, code, message, and data for client logic.
Accounts
GET /accounts
Returns every ShamCash account linked to the authenticated user on the platform.
Response when status is "success"
data is an array of account objects:
{
"status": "success",
"code": "SUCCESS",
"message": "Accounts retrieved successfully.",
"data": [
{
"id": "acc_01hqy8k2example",
"name": "string",
"email": "string",
"phone": "string",
"status": "active",
"subscription_expires_at": "2026-12-31T23:59:59+03:00"
}
]
}
| Field | Type | Description |
|---|---|---|
id | string | Stable identifier for this linked account in the API |
name | string | Display name |
email | string | Email on file for this link |
phone | string | Phone on file for this link |
status | string | "active" — link and subscription allow API use for data endpoints. "inactive" — link disabled or not entitled; /balances and /transactions return SUBSCRIPTION_UNAVAILABLE with details in message. |
subscription_expires_at | string | null | ISO 8601 instant when the current subscription period ends, in Asia/Damascus (with offset). null if there is no fixed end (e.g. not configured yet or lifetime access). |
Recommended practice: Treat status !== "active" or past subscription_expires_at as “cannot use balances/transactions for this account” until the user renews on the platform.
Balances
GET /balances
Returns balance rows for one linked account (three currencies when all are present).
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
account_id | string | Yes | Account id from GET /accounts |
Response when status is "success"
data is an object:
{
"status": "success",
"code": "SUCCESS",
"message": "Balances retrieved successfully.",
"data": {
"account_id": "acc_01hqy8k2example",
"balances": [
{
"currency": { "id": 1, "code": "USD" },
"available": 0.0,
"blocked": 0.0
}
]
}
}
| Field | Description |
|---|---|
account_id | Echo of the requested id |
balances | One entry per currency (1 USD, 2 SYP, 3 EUR) |
balances[].available | Amount available to spend |
balances[].blocked | Amount blocked or held |
Transactions
GET /transactions
Returns incoming (received) transactions for a single linked account, with optional filters.
Query parameters are listed in logical order (the order you should document in client code and OpenAPI).
Query parameters
| # | Parameter | Type | Required | Description |
|---|---|---|---|---|
| 1 | account_id | string | Yes | Linked account id from GET /accounts |
| 2 | start_at | string | No | Inclusive lower bound. Date YYYY-MM-DD or datetime; Asia/Damascus if no offset. |
| 3 | end_at | string | No | Inclusive upper bound; same rules as start_at. |
| 4 | transaction_ids | string | No | Comma-separated list of numeric ids, or repeat the parameter (transaction_ids=1&transaction_ids=2). Only transactions whose ids appear in this list are returned, after applying account_id, date range, and coin_id. See Lookup by transaction id. |
| 5 | coin_id | integer | No | Currency filter: 1 = USD, 2 = SYP, 3 = EUR. Omit to include all currencies. |
| 6 | limit | integer | No | Maximum number of transactions to return. Default: 20. Server may enforce a maximum (e.g. 200). |
Filtering behavior
- Scope is always the given
account_idfor the authenticated user. - If
start_at/end_atare set, keep only rows whoseoccurred_atfalls in that window (Damascus). - If
coin_idis set, keep only that currency. - If
transaction_idsis set, keep only rows whose id is in that set (intersection with the above). If none of the requested ids exist or match the filters,data.transactionsis an empty array — stillSUCCESS, not an error. limitapplies last (e.g. newest first within the filtered set).
Lookup by transaction id
When transaction_ids is provided, the service returns only matching incoming transactions that also satisfy account_id, dates, and coin_id. If no id matches, data.transactions is []. This is expected for idempotent “check these ids” workflows.
Response when status is "success"
{
"status": "success",
"code": "SUCCESS",
"message": "Transactions retrieved successfully.",
"data": {
"account_id": "acc_01hqy8k2example",
"transactions": [
{
"transaction_id": 184627893,
"amount": 0.1,
"currency": { "id": 1, "code": "USD" },
"occurred_at": "2026-04-16T01:22:21+03:00",
"receiver_name": "string",
"sender_name": "string",
"sender_address": "string",
"note": ""
}
]
}
}
For incoming transfers, receiver_name is the display name of your linked ShamCash account (the account that received funds). sender_name is the display name of the other party, and sender_address is the opaque address identifier returned by the payment network for that party.
| Field | Type | Description |
|---|---|---|
transaction_id | integer | Unique transaction id |
amount | number | Received amount |
currency | object | { "id", "code" } — same as balances |
occurred_at | string | ISO 8601 with offset |
receiver_name | string | Display name of the receiving (linked) account |
sender_name | string | Display name of the sending party |
sender_address | string | Opaque identifier for the sender account |
note | string | Payment note; empty string if none |
Error response example
{
"status": "error",
"code": "SUBSCRIPTION_UNAVAILABLE",
"message": "This account has no active subscription. Purchase or renew a plan on shamcash-api.com to use balances and transactions.",
"data": null
}
Other examples of message for the same code:
- "The subscription for this account ended on 2026-01-01. Renew on shamcash-api.com to continue."
- "This ShamCash link is inactive. Reactivate it in your dashboard to continue."
- "No subscription is associated with this account."
Python client: pip install shamcash
Official client for this API: synchronous and async usage, structured error handling, and clear network behavior. GitHub: Melchersman/shamcash · PyPI.