Escrow APIHMAC secured

Build escrow account, payment, and reporting flows from one API surface.

Use Realtimate escrow APIs to create accounts, trigger UPI payment requests, manage stakeholders, transfer ownership, register users, and receive webhook notifications. All partner paths are under /api/external/escrow/*.

UAT: https://ws-uat.realtimate.in/api
View EndpointsView Webhooks
8
documented endpoints
6
POST operations
2
PUT operations

Authenticate

Every CRM call uses the integration JWT in auth. After create, store ownershipToken and send it as ownership-token on request-payment, cancel, and related calls. Send both tokens as received.

Sign Payloads

Send x-payload-signature as HMAC-SHA256 of JSON.stringify(request body) using your ownership HMAC secret. Sign the exact bytes you send.

Verify Webhooks

Callbacks are POSTed with X-Payload-Signature over the raw body using the same HMAC secret. Return 2xx; use UTR for deposit idempotency. Prefer callbackUrl on create; a configured integration default may apply if omitted.

POST/external/escrow/new-account

Create New Account

Creates a new escrow account

Signature: Required

Request Headers

auth
Integration JWT we issue; send it as-is on every CRM call
ownership-token
After create: ownershipToken from sync response / escrow_created; send it as received (not required on create)
x-payload-signature
HMACSHA256(JSON.stringify(request body), ownership HMAC secret)

Mandatory Body

KeyTypeDescription
escrowUseCasestringAllowed values: "eoisale", "eoirental", "rentalsecurity", "saleadv", "rentcol"
descriptionstringA brief description of the escrow account
secondPartiesArrayNon-empty array. Each party requires countryCode, phone, email, firstName, lastName, panNumber
propertyAddressObjectRequires addressLine1, city, state, pincode. addressLine2 is optional
externalRefstringUnique external reference for this escrow account. Duplicate values are rejected

Optional Body

KeyTypeDescription
callbackUrlstringOptional HTTPS URL for escrow_created and new_deposit webhooks. Per-escrow URL wins; if omitted, a configured default for your integration may be used
tokenAmountnumberInitial UPI intent amount. Must be between 0 and 100000
dateDuestringISO 8601 due date. Allowed only when tokenAmount is present and greater than 0, and must be at least 1 hour in the future
method"async" | "sync"Defaults to "async". Use "sync" to wait up to 60 seconds for account details and optional payment details
firstPartiesArrayOptional non-empty array. Each party requires countryCode, phone, email, firstName, lastName
sellersArrayOptional non-empty array. Each seller requires countryCode, phone, email, firstName, lastName
stakeholdersArrayOptional array of registered stakeholders. Each stakeholder requires email

Behavior Notes

  • secondParties cannot overlap with firstParties, sellers, stakeholders, ownership admins, or the creator.
  • CRM integrations: use the integration JWT we issue in auth on every call. Send tokens as issued; do not decode or rewrite them.
  • Sync response (and escrow_created webhook) include ownershipToken — store it and send as ownership-token on later APIs (keep auth as the integration JWT).

Sample Request

{
  "escrowUseCase": "saleadv",
  "description": "For Brigade Metropolis",
  "secondParties": [
    {
      "countryCode": "91",
      "phone": "9999999999",
      "email": "buyer@example.com",
      "firstName": "Mayank",
      "lastName": "Jain",
      "panNumber": "AAAAA1234A"
    }
  ],
  "propertyAddress": {
    "addressLine1": "Tower A, Brigade Metropolis",
    "addressLine2": "Whitefield",
    "city": "Bengaluru",
    "state": "Karnataka",
    "pincode": "560097"
  },
  "callbackUrl": "https://yourapp.com/webhooks/escrow",
  "externalRef": "CRM-REC-1001",
  "tokenAmount": 50000,
  "dateDue": "2026-05-08T13:00:00.000Z",
  "method": "sync"
}

Sample Responses

Async Response
{
  "result": "success"
}
Sync Response (includes ownershipToken)
{
  "accountNum": "RLTM250773061550",
  "accountName": "Realtimate Labs",
  "ifscCode": "ICIC000123",
  "bankName": "ICICI Bank",
  "accountType": "Current",
  "externalRef": "CRM-REC-1001",
  "ownershipToken": "<token value — store and send as ownership-token on later calls>",
  "paymentIntent": "upi://pay?pa=REALTIMATE@icici&pn=Realtimate Labs&tr=REF123&am=50000&cu=INR&mc=5411",
  "paymentLink": "https://uat.realtimate.in/payment/abc123",
  "dateDue": "2026-05-08T13:00:00.000Z",
  "amount": "50000"
}

Webhook Notifications

Callbacks for escrow events

Webhooks are POSTed to the callbackUrl from create when provided. If omitted, a configured default URL for your integration may be used. Available today: escrow_created and new_deposit (VAN credits only). Each request includes Content-Type: application/json and X-Payload-Signature (HMAC-SHA256 hex of the raw body, same ownership HMAC secret as outbound API calls). Return 2xx; use UTR for deposit idempotency. escrow_created includes ownershipToken for later ownership-token headers.

On UAT, Realtimate can help you simulate a VAN deposit so you can verify your webhook — ask your Realtimate contact for the test steps. The public docs cover payload shape and signature verification only.

Account Created Callback

Sent after the escrow account and virtual account details are ready (usually 30-60 seconds). POST with Content-Type application/json and X-Payload-Signature (HMAC of the raw body using your ownership secret). Includes ownershipToken — store it and send as ownership-token on later API calls.

Verify incoming webhook

const expected = crypto
  .createHmac("sha256", hmacSecret)
  .update(rawBodyString)
  .digest("hex");
// timing-safe compare with header X-Payload-Signature
// then JSON.parse(rawBodyString)
{
  "event": "escrow_created",
  "externalRef": "CRM-REC-1001",
  "accountNum": "RLTM000124",
  "accountName": "Mark Singh",
  "ifscCode": "ICIC000123",
  "bankName": "ICICI Bank",
  "status": "created",
  "ownershipToken": "<token value — send as ownership-token on later calls>"
}

Planned

Not live yet

  • POST /external/escrow/get-status — poll escrow / payments / deposits by accountNum or externalRef when a webhook was missed.
  • Webhook payment_requested — fired when an async payment link is ready. Until then, use method: "sync" on request-payment.
  • Webhook payment_cancelled — fired after cancel. Until then, use the cancel HTTP response.