Check what a sender can still send

Read a sender's caps and what is left in each window before a big payout, so a transfer does not pause on payday.

This recipe reads a sender's caps and how much is left in each limit window, so you can check a large payout before you send it. It is for an operations analyst at a US remittance app that verifies its own senders (remitters) and wants no transfers paused on payday.

Status. Available when your business has a limits policy.

Money example

Maria wants to send 1,500 USD today.

  1. Her limits are 1,000 USD per transfer and 3,000 USD a day, with 0 used today.
  2. 1,500 USD is over the per-transfer cap, so Gravv would create the transfer paused instead of refusing it.
  3. A higher verification tier lifts the cap. If you verify her to that tier first and then send, the transfer does not pause.

Before you start

  • Your business has a limits policy. Without one, both reads return 404 and no Gravv limits apply.
  • The sender's id. For your customers, this is the customer id. For senders you verify yourself, it is the remitter_id you send in additional_information.remitter_verification.

Find out what is required

The limits response tells you how Gravv checks the sender and how much they can still send. Read these fields:

Field Meaning
mode enforce: a breach pauses the transfer. shadow: Gravv only records a breach. off: no checks
blocked true: Gravv refuses every transfer with 422 ERROR_CODE_SUBJECT_BLOCKED
windows.<window>.cap_usd, used_usd, remaining_usd USD strings for per_transfer, daily, weekly, monthly and annual (the last 12 months)
cap_usd null No cap in that window, but only when caps_basis is tier
usage_available false Gravv could not read usage, so used_usd and remaining_usd are null
next_tier, candidate_tiers The caps a higher tier allows

Steps

1. Read a remitter's limits

curl --request GET \
 --url https://api.gravv.xyz/v1/limits/remitters/rem-20431 \
 --header 'Api-Key: <API_KEY>'
const response = await fetch("https://api.gravv.xyz/v1/limits/remitters/rem-20431", {
method: "GET",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
},
});
console.log(response.status, await response.json());
import os

import requests

response = requests.get(
"https://api.gravv.xyz/v1/limits/remitters/rem-20431",
headers={
    "Api-Key": os.environ["GRAVV_API_KEY"],
},
)
print(response.status_code, response.json())
{
  "data": {
    "subject_type": "remitter",
    "subject_id": "rem-20431",
    "tier_code": "",
    "tier_assignment": "per_transfer_attestation",
    "caps_basis": "floor",
    "mode": "enforce",
    "blocked": false,
    "usage_available": true,
    "as_of": "2026-10-13T09:15:22Z",
    "windows": {
      "per_transfer": { "cap_usd": "1000.00", "used_usd": null, "remaining_usd": null },
      "daily": { "cap_usd": "3000.00", "used_usd": "0.00", "remaining_usd": "3000.00" },
      "weekly": { "cap_usd": null, "used_usd": "0.00", "remaining_usd": null },
      "monthly": { "cap_usd": "10000.00", "used_usd": "0.00", "remaining_usd": "10000.00" },
      "annual": { "cap_usd": "0.00", "used_usd": "0.00", "remaining_usd": "0.00", "requires_approval": true }
    },
    "next_tier": null,
    "candidate_tiers": [
      {
        "tier_code": "STARTER",
        "rank": 0,
        "tier_caps": { "per_transfer": "1000", "daily": "3000", "weekly": null, "monthly": "10000", "annual": null, "annual_requires_approval": true },
        "caps": { "per_transfer": "1000", "daily": "3000", "weekly": null, "monthly": "10000", "annual": null, "annual_requires_approval": true }
      }
    ]
  },
  "error": null
}

1,500 is more than the per_transfer cap of 1,000, so the transfer would pause with pause_reason per_transfer. Tier codes such as STARTER come from your business's limits policy. Read them from this response and never hard-code them. Gravv accepts any string as a remitter id. For an id it has never seen, Gravv uses the policy's default tier.

2. Read a customer's limits

The response has the same shape as in step 1, with subject_type set to customer.

curl --request GET \
 --url https://api.gravv.xyz/v1/customers/5be6128e-18c2-4797-a142-ea7d17be3111/limits \
 --header 'Api-Key: <API_KEY>'
const response = await fetch("https://api.gravv.xyz/v1/customers/5be6128e-18c2-4797-a142-ea7d17be3111/limits", {
method: "GET",
headers: {
"Api-Key": process.env.GRAVV_API_KEY,
},
});
console.log(response.status, await response.json());
import os

import requests

response = requests.get(
"https://api.gravv.xyz/v1/customers/5be6128e-18c2-4797-a142-ea7d17be3111/limits",
headers={
    "Api-Key": os.environ["GRAVV_API_KEY"],
},
)
print(response.status_code, response.json())

3. Compare before you send

Convert the planned amount to USD and compare it with the smallest remaining_usd and with the per_transfer cap. If a transfer would pause, plan to verify that sender first. Do not split a payment to get under a cap.

If a transfer has already paused, Stay within transfer limits shows how to respond to it.

What can go wrong

Response Why Fix
404 not found: no limits policy applies Your business has no limits policy No Gravv limits apply, so there is nothing to check
404 not found: subject The customer id is not in your business Fix the id
400 subject_id "x" is not a customer id The id on the customer route is not a UUID Use the customer's UUID
404 with the plain-text body 404 page not found An empty id, as in /v1/limits/remitters/ Add the id
503 ERROR_CODE_LIMITS_UNAVAILABLE Gravv cannot read limits right now Retry, and wait longer before each new attempt
A remitter shows no usage although they sent today Usage counts only transfers that carried remitter_verification with exactly this remitter_id (case matters) Send the same id every time
An annual cap of "0.00" with requires_approval true An annual allowance needs Gravv's approval Transfers past it pause for review

Webhooks you will receive

Reading limits sends no webhook. If a transfer later breaches a cap, Gravv sends transfer.requires_information. Its limit_details object holds breached_window, cap_usd, used_usd, remaining_usd and requirements.

Testing in sandbox

Your sandbox business needs a sandbox limits policy, and Gravv sets it up. If the sandbox policy is in shadow mode, both reads return 200, but Gravv only records a breach and never pauses the transfer. To see a pause, ask support to put the policy in enforce mode.

Reference

Was this page helpful?