Cards
Virtual Visa and Mastercard cards in US dollars. A card is funded from your cards balance and can be frozen, emptied to the cards balance or terminated at any time. Amounts are in US cents. When the issuer’s answer to an action is not final, the API returns 202 and the result arrives by webhook.
/v1/cardsCreate a cardGET/v1/cards/{id}Retrieve a cardGET/v1/cardsList cardsPOST/v1/cards/{id}/fundFund a cardPOST/v1/cards/{id}/withdrawWithdraw from a cardPOST/v1/cards/{id}/freezeFreeze a cardPOST/v1/cards/{id}/unfreezeUnfreeze a cardPOST/v1/cards/{id}/terminateTerminate a cardThe card object
Attributes
Unique identifier (UUID).
true for live objects, false for test objects.
Always card.
agent cards belong to an AI agent and have no cardholder.
teamcustomeragentpending while the issuer creates the card, failed if it could not.
pendingactivefrozenterminatedfailedCardholder ID.
Agent cards only.
Your label for the card.
visamastercardLast 4 digits of the card number.
Always USD.
Card balance in US cents.
Single-use card: it can be paid once; later payments are declined. It cannot be funded or withdrawn from.
{ amount, interval } with interval daily or per_transaction. Always null for single-use cards.
Creation time, ISO 8601 (UTC).
{
"id": "ce2f0aea-7f87-4cbd-8383-03129d1253e0",
"object": "card",
"livemode": false,
"type": "customer",
"status": "active",
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"agent_name": null,
"label": "Subscriptions",
"network": "visa",
"last4": "5904",
"exp_month": 10,
"exp_year": 2029,
"currency": "USD",
"balance": 950,
"single_use": false,
"spending_limit": {
"amount": 20000,
"interval": "daily"
},
"created_at": "2026-10-30T13:47:06.394Z",
"terminated_at": null
}Create a card
Issues a card to a verified cardholder (or to an AI agent with type: "agent"). amount is taken from your cards balance: it must cover the issuing fee plus at least $1. Returns 201 when the card is active, or 202 with status: "pending" while the issuer finishes or when its answer is not final yet; card.issued or card.issue_failed follows. The money returns to the cards balance only once a failure is final.
Key roles: Owner or Finance
Body
Initial funding in US cents, taken from the cards balance. Up to 10,000,000.
Cardholder ID. Required unless type is agent.
teamagent for an agent card. For other cards, the card takes the type of its cardholder.
teamcustomeragentRequired for agent cards. Up to 60 characters.
Your label, up to 60 characters.
visavisamastercardfalseThe card can be paid once. Later payments are declined and nothing is charged. It cannot be funded or withdrawn from; its remaining balance returns to the cards balance when it is terminated (automatically 30 days after issue, or with terminate).
Spending limit. Not allowed with single_use: true (the card amount is the limit): sending both returns 400 parameter_invalid.
Show child attributes
In US cents.
dailyper_transactionReturns
Returns the new card object with 201, or 202 when the outcome is not final yet.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
400 | cardholder_ | The cardholder’s identity is not verified yet. |
400 | amount_ | Amount below the minimum (for cards: issuing fee plus $1). |
400 | parameter_ | A parameter has the wrong type or value. See param. |
402 | balance_ | Your balance (or cards balance) does not cover the amount and the fee. |
400 | agent_ | Agent cards are not set up yet. An Owner must issue the first agent card from the dashboard. |
402 | provider_ | The operator or the card issuer declined. message gives their reason. |
curl https://api.monerail.com/v1/cards \
-H "Authorization: Bearer $MONERAIL_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45" \
-d '{
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"type": "customer",
"label": "Subscriptions",
"amount": 1000,
"spending_limit": {
"amount": 20000,
"interval": "daily"
}
}'const res = await fetch('https://api.monerail.com/v1/cards', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45',
},
body: JSON.stringify({
cardholder: '5df6acd9-4bac-4e19-869c-fcde6b79f389',
type: 'customer',
label: 'Subscriptions',
amount: 1000,
spending_limit: {
amount: 20000,
interval: 'daily',
},
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.post(
"https://api.monerail.com/v1/cards",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}", "Idempotency-Key": "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45"},
json={
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"type": "customer",
"label": "Subscriptions",
"amount": 1000,
"spending_limit": {
"amount": 20000,
"interval": "daily",
},
},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/cards');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
'Content-Type: application/json',
'Idempotency-Key: a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45',
],
CURLOPT_POSTFIELDS => json_encode([
'cardholder' => '5df6acd9-4bac-4e19-869c-fcde6b79f389',
'type' => 'customer',
'label' => 'Subscriptions',
'amount' => 1000,
'spending_limit' => [
'amount' => 20000,
'interval' => 'daily',
],
]),
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
payload, err := json.Marshal(map[string]any{
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"type": "customer",
"label": "Subscriptions",
"amount": 1000,
"spending_limit": map[string]any{
"amount": 20000,
"interval": "daily",
},
})
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.monerail.com/v1/cards", bytes.NewReader(payload))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
String body = """
{
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"type": "customer",
"label": "Subscriptions",
"amount": 1000,
"spending_limit": {
"amount": 20000,
"interval": "daily"
}
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/cards"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/cards")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
req["Content-Type"] = "application/json"
req["Idempotency-Key"] = "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45"
req.body = JSON.generate({
cardholder: "5df6acd9-4bac-4e19-869c-fcde6b79f389",
type: "customer",
label: "Subscriptions",
amount: 1000,
spending_limit: {
amount: 20000,
interval: "daily",
},
})
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.monerail.com/v1/cards");
request.Headers.Add("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45");
request.Content = JsonContent.Create(new
{
cardholder = "5df6acd9-4bac-4e19-869c-fcde6b79f389",
type = "customer",
label = "Subscriptions",
amount = 1000,
spending_limit = new
{
amount = 20000,
interval = "daily",
},
});
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"id": "ce2f0aea-7f87-4cbd-8383-03129d1253e0",
"object": "card",
"livemode": false,
"type": "customer",
"status": "active",
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"agent_name": null,
"label": "Subscriptions",
"network": "visa",
"last4": "5904",
"exp_month": 10,
"exp_year": 2029,
"currency": "USD",
"balance": 950,
"single_use": false,
"spending_limit": {
"amount": 20000,
"interval": "daily"
},
"created_at": "2026-10-30T13:47:06.394Z",
"terminated_at": null
}Retrieve a card
The full card number and CVC are never returned by the API. An Owner or Finance member can display them for 60 seconds in the dashboard (Show card details).
Key roles: Every role
Path parameters
ID of the card.
Returns
Returns the card object.
curl https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0 \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0', {
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.get(
"https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}"},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
],
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest(http.MethodGet, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0");
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"id": "ce2f0aea-7f87-4cbd-8383-03129d1253e0",
"object": "card",
"livemode": false,
"type": "customer",
"status": "active",
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"agent_name": null,
"label": "Subscriptions",
"network": "visa",
"last4": "5904",
"exp_month": 10,
"exp_year": 2029,
"currency": "USD",
"balance": 950,
"single_use": false,
"spending_limit": {
"amount": 20000,
"interval": "daily"
},
"created_at": "2026-10-30T13:47:06.394Z",
"terminated_at": null
}List cards
Newest first.
Key roles: Every role
Query parameters
Only the cards with this status.
pendingactivefrozenterminatedfailedOnly the cards of this cardholder (ID).
20Number of objects to return, 1 to 100.
Cursor: the ID of the last object of the previous page.
Returns
Returns a list object: data holds up to limit card objects, and has_more tells whether more follow.
curl "https://api.monerail.com/v1/cards?status=active&limit=10" \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerail.com/v1/cards?status=active&limit=10', {
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.get(
"https://api.monerail.com/v1/cards",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}"},
params={"status": "active", "limit": 10},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/cards?status=active&limit=10');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
],
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest(http.MethodGet, "https://api.monerail.com/v1/cards?status=active&limit=10", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/cards?status=active&limit=10"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/cards?status=active&limit=10")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.monerail.com/v1/cards?status=active&limit=10");
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"object": "list",
"url": "/v1/cards",
"data": [
{
"id": "ce2f0aea-7f87-4cbd-8383-03129d1253e0",
"object": "card",
"livemode": false,
"type": "customer",
"status": "active",
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"agent_name": null,
"label": "Subscriptions",
"network": "visa",
"last4": "5904",
"exp_month": 10,
"exp_year": 2029,
"currency": "USD",
"balance": 950,
"single_use": false,
"spending_limit": {
"amount": 20000,
"interval": "daily"
},
"created_at": "2026-10-30T13:47:06.394Z",
"terminated_at": null
}
],
"has_more": false
}Fund a card
Moves money from the cards balance to the card. Like every card action, returns 202 instead of 200 when the issuer’s answer is not final yet: the operation is not failed, and its result arrives by webhook (card.funded). Not available for single-use cards.
Key roles: Owner or Finance
Path parameters
ID of the card.
Body
In US cents, up to 10,000,000.
Returns
Returns the card object with 200, or 202 when the issuer’s answer is not final yet.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
402 | balance_ | Your balance (or cards balance) does not cover the amount and the fee. |
400 | card_ | Single-use cards cannot be funded or withdrawn from. |
409 | card_ | Another operation is running on this card. Retry in a few seconds. |
curl https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/fund \
-H "Authorization: Bearer $MONERAIL_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45" \
-d '{
"amount": 5000
}'const res = await fetch('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/fund', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45',
},
body: JSON.stringify({
amount: 5000,
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.post(
"https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/fund",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}", "Idempotency-Key": "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45"},
json={
"amount": 5000,
},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/fund');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
'Content-Type: application/json',
'Idempotency-Key: a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => 5000,
]),
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
payload, err := json.Marshal(map[string]any{
"amount": 5000,
})
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/fund", bytes.NewReader(payload))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
String body = """
{
"amount": 5000
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/fund"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/fund")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
req["Content-Type"] = "application/json"
req["Idempotency-Key"] = "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45"
req.body = JSON.generate({
amount: 5000,
})
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/fund");
request.Headers.Add("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45");
request.Content = JsonContent.Create(new
{
amount = 5000,
});
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"id": "ce2f0aea-7f87-4cbd-8383-03129d1253e0",
"object": "card",
"livemode": false,
"type": "customer",
"status": "active",
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"agent_name": null,
"label": "Subscriptions",
"network": "visa",
"last4": "5904",
"exp_month": 10,
"exp_year": 2029,
"currency": "USD",
"balance": 5950,
"single_use": false,
"spending_limit": {
"amount": 20000,
"interval": "daily"
},
"created_at": "2026-10-30T13:47:06.394Z",
"terminated_at": null
}Withdraw from a card
Moves money from the card back to the cards balance. At least $1 must stay on the card. Not available for single-use cards. card.withdrawn confirms it.
Key roles: Owner or Finance
Path parameters
ID of the card.
Body
In US cents.
Returns
Returns the card object with 200, or 202 when the issuer’s answer is not final yet.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
400 | card_ | At least $1 must stay on the card. |
400 | card_ | Single-use cards cannot be funded or withdrawn from. |
409 | card_ | Another operation is running on this card. Retry in a few seconds. |
curl https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/withdraw \
-H "Authorization: Bearer $MONERAIL_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45" \
-d '{
"amount": 500
}'const res = await fetch('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/withdraw', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45',
},
body: JSON.stringify({
amount: 500,
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.post(
"https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/withdraw",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}", "Idempotency-Key": "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45"},
json={
"amount": 500,
},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/withdraw');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
'Content-Type: application/json',
'Idempotency-Key: a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => 500,
]),
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
payload, err := json.Marshal(map[string]any{
"amount": 500,
})
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/withdraw", bytes.NewReader(payload))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
String body = """
{
"amount": 500
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/withdraw"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/withdraw")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
req["Content-Type"] = "application/json"
req["Idempotency-Key"] = "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45"
req.body = JSON.generate({
amount: 500,
})
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/withdraw");
request.Headers.Add("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45");
request.Content = JsonContent.Create(new
{
amount = 500,
});
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"id": "ce2f0aea-7f87-4cbd-8383-03129d1253e0",
"object": "card",
"livemode": false,
"type": "customer",
"status": "active",
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"agent_name": null,
"label": "Subscriptions",
"network": "visa",
"last4": "5904",
"exp_month": 10,
"exp_year": 2029,
"currency": "USD",
"balance": 450,
"single_use": false,
"spending_limit": {
"amount": 20000,
"interval": "daily"
},
"created_at": "2026-10-30T13:47:06.394Z",
"terminated_at": null
}Freeze a card
Declines every new payment until the card is unfrozen. card.frozen confirms it.
Key roles: Owner, Finance or Approver
Path parameters
ID of the card.
Returns
Returns the card object with 200, or 202 when the issuer’s answer is not final yet.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
400 | card_ | The card is already frozen. |
curl -X POST https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/freeze \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/freeze', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.post(
"https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/freeze",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}"},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/freeze');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
],
CURLOPT_POSTFIELDS => '',
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest(http.MethodPost, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/freeze", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/freeze"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/freeze")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/freeze");
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"id": "ce2f0aea-7f87-4cbd-8383-03129d1253e0",
"object": "card",
"livemode": false,
"type": "customer",
"status": "frozen",
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"agent_name": null,
"label": "Subscriptions",
"network": "visa",
"last4": "5904",
"exp_month": 10,
"exp_year": 2029,
"currency": "USD",
"balance": 950,
"single_use": false,
"spending_limit": {
"amount": 20000,
"interval": "daily"
},
"created_at": "2026-10-30T13:47:06.394Z",
"terminated_at": null
}Unfreeze a card
Accepts payments again. card.unfrozen confirms it.
Key roles: Owner, Finance or Approver
Path parameters
ID of the card.
Returns
Returns the card object with 200, or 202 when the issuer’s answer is not final yet.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
400 | card_ | The card is not frozen. |
curl -X POST https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/unfreeze \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/unfreeze', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.post(
"https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/unfreeze",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}"},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/unfreeze');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
],
CURLOPT_POSTFIELDS => '',
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest(http.MethodPost, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/unfreeze", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/unfreeze"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/unfreeze")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/unfreeze");
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"id": "ce2f0aea-7f87-4cbd-8383-03129d1253e0",
"object": "card",
"livemode": false,
"type": "customer",
"status": "active",
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"agent_name": null,
"label": "Subscriptions",
"network": "visa",
"last4": "5904",
"exp_month": 10,
"exp_year": 2029,
"currency": "USD",
"balance": 950,
"single_use": false,
"spending_limit": {
"amount": 20000,
"interval": "daily"
},
"created_at": "2026-10-30T13:47:06.394Z",
"terminated_at": null
}Terminate a card
Closes the card for good. Its remaining balance returns to the cards balance. This cannot be undone. card.terminated confirms it.
Key roles: Owner or Finance
Path parameters
ID of the card.
Returns
Returns the card object with 200, or 202 when the issuer’s answer is not final yet.
curl -X POST https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/terminate \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/terminate', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.post(
"https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/terminate",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}"},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/terminate');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
],
CURLOPT_POSTFIELDS => '',
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest(http.MethodPost, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/terminate", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/terminate"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/terminate")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.monerail.com/v1/cards/ce2f0aea-7f87-4cbd-8383-03129d1253e0/terminate");
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"id": "ce2f0aea-7f87-4cbd-8383-03129d1253e0",
"object": "card",
"livemode": false,
"type": "customer",
"status": "terminated",
"cardholder": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"agent_name": null,
"label": "Subscriptions",
"network": "visa",
"last4": "5904",
"exp_month": 10,
"exp_year": 2029,
"currency": "USD",
"balance": 0,
"single_use": false,
"spending_limit": {
"amount": 20000,
"interval": "daily"
},
"created_at": "2026-10-30T13:47:06.394Z",
"terminated_at": "2026-10-30T13:47:09.807Z"
}