Grey Finance Business API (1.0)

Download OpenAPI specification:

URL: https://grey.co License: LicenseRef-scancode-proprietary-license

The Grey Finance Business API lets you programmatically move money, check balances, look up exchange rates, and manage integration settings for your Grey Finance business account.

Prerequisites

  • A registered business account with Grey Finance.
  • Valid API credentials (see API Key Management below).
  • An HTTPS-enabled environment for secure communication.

Base URLs

Environment URL
Sandbox https://businessapi-sandbox.grey.co
Production https://businessapi.grey.co

API Key Management

All API requests must be authenticated using an API key. The key should be included in the Authorization header of every request.

To generate your API key, log in to the dashboard:

  1. Navigate to your Grey Finance business dashboard.
  2. Go to Integrations › API keys and generate your key.

API keys consist of a Public Key and a Secret Key:

  • Public Key — starts with gbpk_ (e.g. gbpk_abc123def456ghi789).
  • Secret Key — starts with gbsk_ (e.g. gbsk_xyz789uvw456rst123).

Secure your API key

  • Copy the generated key immediately — it will not be shown again.
  • Store it securely in your application's environment variables.
  • Never commit API keys to version control.

How to Authorize Requests

Include your API key in the Authorization header of every request:

curl -X GET "https://${baseUrl}/v1/grey-tags/johndoe" \
  -H "Authorization: Bearer gbsk_xxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json"

Idempotency

Money-moving requests can be made safe to retry in two ways:

  • Send an X-Idempotency-Key header, or
  • Include a reference in the body of a payout (/v1/charge/payout).

When a request is retried with the same idempotency key — or the same reference for the same business — Grey returns the original response instead of performing the payment again, and sets X-Idempotent-Replayed: true on the replayed response. A duplicate that arrives while the first is still processing returns 409 Conflict.

Only successful (2xx) responses are replayed, so a payout that failed can be retried under the same reference. Reusing a reference with a different request body is rejected with 409 Conflict, so a genuine second payment is never silently swallowed. Replays are matched for 24 hours.

Webhook Event Types

Currently we support three event types for webhooks:

Event Description
transaction.created New transaction created
transaction.success Transaction completed successfully
transaction.failed Transaction failed

Every webhook payload echoes your client_reference (when you supplied a reference on the request) alongside Grey's own transaction_reference, so you can match each event to your records. You can also look a transaction up at any time with GET /api/v1/transactions?client_reference=....

How to Validate Webhook Signatures

Every webhook payload includes a cryptographic signature in the X-Webhook-Signature header, computed with your webhook secret and the raw request body using HMAC-SHA256.

X-Webhook-Signature: sha256=abc123def456...

Verification steps

  1. Get the signature from the X-Webhook-Signature header.
  2. Compute an HMAC-SHA256 hash of the raw JSON body using your webhook secret.
  3. Compare the two values — if they match the webhook is authentic.
package main

import (
  "crypto/hmac"
  "crypto/sha256"
  "encoding/hex"
  "io"
  "net/http"
  "strings"
)

const webhookSecret = "your-webhook-secret-here"

func validateSignature(payload []byte, signatureHeader, secret string) bool {
  if !strings.HasPrefix(signatureHeader, "sha256=") {
    return false
  }
  expectedSignature := strings.TrimPrefix(signatureHeader, "sha256=")
  h := hmac.New(sha256.New, []byte(secret))
  h.Write(payload)
  computedSignature := hex.EncodeToString(h.Sum(nil))
  return hmac.Equal([]byte(computedSignature), []byte(expectedSignature))
}

func webhookHandler(w http.ResponseWriter, r *http.Request) {
  body, err := io.ReadAll(r.Body)
  if err != nil {
    http.Error(w, "Failed to read request body", http.StatusBadRequest)
    return
  }
  defer r.Body.Close()

  signatureHeader := r.Header.Get("X-Webhook-Signature")
  if signatureHeader == "" {
    http.Error(w, "Missing signature header", http.StatusUnauthorized)
    return
  }

  if !validateSignature(body, signatureHeader, webhookSecret) {
    http.Error(w, "Invalid signature", http.StatusUnauthorized)
    return
  }

  w.WriteHeader(http.StatusOK)
  w.Write([]byte("Webhook received and validated successfully"))
}

Sample Webhook Payload

Headers:

Content-Type: application/json
X-Webhook-Event: transaction.success
X-Webhook-Delivery-ID: delivery-uuid-123
X-Webhook-Signature: sha256=abc123def456...
User-Agent: Grey-Webhook/1.0

Body:

{
  "event_type": "transaction.success",
  "transaction_id": "txn_abc123def456",
  "transaction_reference": "GREY7F3K2MQ9",
  "client_reference": "INV-2024-001",
  "business_id": "business-uuid",
  "amount": 1000.00,
  "source_currency": "USD",
  "destination_currency": "EUR",
  "status": "completed",
  "fees": 5.00,
  "fee_currency": "USD",
  "exchange_rate": 0.85,
  "created_at": "2024-01-15T10:30:00Z",
  "completed_at": "2024-01-15T11:30:00Z",
  "transaction_type": "p2p"
}

Reference Data

Look up supported payout methods, currency pairs, and Grey Tags.

Validate Grey Tag

Check if a Grey Tag (username) exists and retrieve basic user information. Use this before initiating a P2P transfer.

Authorizations:
BearerAPIKey
path Parameters
tag
required
string
Example: johndoe

The Grey Tag to validate.

Responses

Response samples

Content type
application/json
{
  • "status": "success",
  • "message": "User fetched successfully",
  • "data": {
    }
}

List Supported Payout Methods

Get the list of payout methods you can use with /v1/charge/payout, including the supported currencies, countries, and the required beneficiary fields for each.

Authorizations:
BearerAPIKey

Responses

Response samples

Content type
application/json
{
  • "status": "success",
  • "message": "Payout methods fetched successfully",
  • "data": {
    }
}

List Supported Currency Pairs

Get the list of currency pairs you can swap with /v1/charge/swap and quote with /v1/currency/rate.

Authorizations:
BearerAPIKey

Responses

Response samples

Content type
application/json
{
  • "status": "success",
  • "message": "Currency pairs fetched successfully",
  • "data": {
    }
}

Wallets

Query business wallet balances.

Get Wallet Balances

Get your Grey Finance business wallet balances across all currencies. Returns one entry per currency wallet your business has provisioned, sorted alphabetically by currency code.

Use this to reconcile balances on your end before initiating swaps, payouts, or P2P transfers.

Authorizations:
BearerAPIKey

Responses

Response samples

Content type
application/json
{
  • "status": "success",
  • "message": "Balances fetched successfully",
  • "data": {
    }
}

Transactions

Create P2P transfers, currency swaps, payouts, and check exchange rates.

Send Money to a User (P2P Transfer)

Send money to someone using their Grey Tag (username).

Authorizations:
BearerAPIKey
Request Body schema: application/json
required
source_amount
required
number

Amount to send.

source_currency
required
string

ISO currency code of the source wallet.

destination_currency
required
string

ISO currency code for the recipient.

username
required
string

Recipient's Grey Tag.

description
required
string

A note or reference for this transfer.

Responses

Request samples

Content type
application/json
{
  • "source_amount": 50,
  • "source_currency": "USD",
  • "destination_currency": "USD",
  • "username": "recipient_username",
  • "description": "Payment for services"
}

Response samples

Content type
application/json
{
  • "status": "success",
  • "message": "transaction is processing",
  • "data": {
    }
}

Convert Currency (Swap)

Convert one currency to another (e.g. USD to EUR).

Authorizations:
BearerAPIKey
Request Body schema: application/json
required
source_amount
required
number

Amount to convert.

source_currency
required
string

Currency to convert from.

destination_currency
required
string

Currency to convert to.

Responses

Request samples

Content type
application/json
{
  • "source_amount": 1000,
  • "source_currency": "USD",
  • "destination_currency": "EUR"
}

Response samples

Content type
application/json
{
  • "status": "success",
  • "message": "Swap processing has been initiated",
  • "data": {
    }
}

Check Exchange Rates

Get current exchange rates and fees before making a transaction. The transaction_type field must be one of withdraw, deposit, or swap.

Authorizations:
BearerAPIKey
Request Body schema: application/json
required
source_amount
required
number

Amount to quote.

source_currency
required
string
destination_currency
required
string
transaction_type
required
string
Enum: "withdraw" "deposit" "swap"

Type of transaction to quote fees for.

Responses

Request samples

Content type
application/json
{
  • "source_amount": 1000,
  • "source_currency": "USD",
  • "destination_currency": "EUR",
  • "transaction_type": "swap"
}

Response samples

Content type
application/json
{
  • "status": "success",
  • "message": "Currency rate created successfully",
  • "data": {
    }
}

Withdraw to Bank Account

Send money from your Grey Finance business account to a bank account. Use /v1/payout-methods to discover supported rails and required beneficiary fields.

Pass your own reference to reconcile the payout against your records — it is echoed back as client_reference on the response, on GET /api/v1/transactions, and on webhooks. The same reference also makes the request idempotent (see the Idempotency section).

Authorizations:
BearerAPIKey
Request Body schema: application/json
required
source_amount
required
number

Amount to pay out.

source_currency
required
string
destination_currency
required
string
description
string

A note or reference for this payout.

reference
string <= 128 characters

Your own reference for this payout — for example an invoice, order, or ledger id. It is stored and echoed back as client_reference on the response, on transaction fetches (GET /api/v1/transactions), and on webhooks, so you can reconcile a payment against your own records.

It also acts as an idempotency key: retrying a payout with the same reference returns the original response instead of sending a second payment (see the Idempotency section). Optional. Does not affect Grey's own reference.

required
object (Beneficiary)

Recipient details for a payout. The required fields depend on the payout method and destination country — use /v1/payout-methods to discover what is needed.

Responses

Request samples

Content type
application/json
{
  • "source_amount": 500,
  • "source_currency": "USD",
  • "destination_currency": "USD",
  • "description": "Business payout",
  • "reference": "INV-1001",
  • "beneficiary": {
    }
}

Response samples

Content type
application/json
{
  • "status": "success",
  • "message": "Your withdrawal is processing",
  • "data": {
    }
}

List / Fetch Transactions

Retrieve your business's transactions, most recent first. Filter by client_reference to look up the payment(s) you created with a given reference, or by Grey reference for a specific transaction. Every row includes client_reference for reconciliation.

Authorizations:
BearerAPIKey
query Parameters
client_reference
string
Example: client_reference=INV-1001

Return only transactions you created with this reference.

reference
string

Return the transaction with this Grey reference.

page
integer >= 1

Page number for pagination.

limit
integer

Number of results per page.

Responses

Response samples

Content type
application/json
{
  • "status": "success",
  • "message": "Transactions retrieved",
  • "data": [
    ]
}

Sandbox

Sandbox-only helpers for testing your integration (not available in production).

Top Up a Wallet (Sandbox Only)

Credit your business wallet with test funds so you can exercise payouts, swaps, and P2P transfers without making a real deposit.

This endpoint is only available in the sandbox environment — calling it against production returns 404 Not Found.

The credit is applied immediately to the available_balance of the wallet for the requested currency. If your business does not yet have a wallet for that currency the request fails.

Authorizations:
BearerAPIKey
Request Body schema: application/json
required
currency
required
string

ISO currency code (fiat) or ticker (crypto) of the wallet to credit.

amount
required
number

Amount of test funds to credit. Must be greater than 0.

Responses

Request samples

Content type
application/json
{
  • "currency": "USD",
  • "amount": 1000
}

Response samples

Content type
application/json
{
  • "status": "success",
  • "message": "Wallet topped up successfully",
  • "data": {
    }
}

Developer

Manage API keys and webhooks for your integration.

Create API Key

Create a new API key for your business. The secret key is returned only once in the response — store it securely.

Note: This endpoint requires dashboard authentication (Bearer JWT), not an API key.

Authorizations:
BearerJWT
Request Body schema: application/json
required
name
required
string

Friendly name for the key.

description
required
string
expires_at
string <date-time>

Optional expiry timestamp. Omit for no expiry.

ip_whitelist
Array of strings

IP addresses allowed to use this key.

ip_whitelist_enabled
boolean

Whether to enforce IP whitelist.

Responses

Request samples

Content type
application/json
{
  • "name": "grey-api-key",
  • "description": "This key is to process transactions",
  • "expires_at": "2024-01-15T10:30:00Z",
  • "ip_whitelist": [
    ],
  • "ip_whitelist_enabled": true
}

Response samples

Content type
application/json
{
  • "id": "0b6ed51d-ccfb-4264-8d29-8f5753c67e92",
  • "business_id": "0b6ed51d-ccfb-4264-8d29-8f5753c67e92",
  • "name": "grey-api-key",
  • "description": "This key is to process transactions",
  • "active": true,
  • "key": "gbpk_abc123def456ghi789",
  • "secret_key": "gbsk_abc123def456ghi789",
  • "ip_whitelist": [
    ],
  • "ip_whitelist_enabled": true,
  • "permissions": [
    ],
  • "created_at": "2024-01-15T10:30:00Z",
  • "updated_at": "2024-01-15T10:30:00Z",
  • "last_used_at": "2024-01-15T10:30:00Z",
  • "message": "Api key created successfully"
}

Create Webhook

Configure a webhook endpoint for your business to receive real-time notifications about transaction events.

Note: This endpoint requires dashboard authentication (Bearer JWT), not an API key.

Authorizations:
BearerJWT
Request Body schema: application/json
required
url
required
string <uri>

The HTTPS endpoint that will receive webhook events.

secret
required
string >= 8 characters

Secret used to compute HMAC-SHA256 signatures.

event_types
required
Array of strings
Items Enum: "transaction.created" "transaction.success" "transaction.failed"

Events to subscribe to.

description
string

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{}