Brails API access from Supabase Edge Functions
Keep your application on Supabase and give Brails-bound requests a stable outbound route. A selectively configured QuotaGuard client lets your frontend, database and unrelated API traffic stay on their existing paths while the Brails integration uses the addresses approved for its account.
This guide adds the Brails-specific configuration and diagnostic workflow to the QuotaGuard Supabase Edge Functions guide. Use that platform guide for the general client setup. Use this guide to connect the account policy, sandbox endpoint, secret names, result interpretation and production handoff.
The connection you are configuring
Authorized backend operation
|
Supabase Edge Function
|
Explicit proxy-aware Deno client
|
QuotaGuard outbound route
|
Brails HTTPS API
Browser traffic, incoming Brails webhooks and unrelated
Supabase requests keep their existing routes.
The relevant address is the source observed by the API receiving the request. The hostname in the request URL is the destination. A customer’s browser address is a different identity again.
For an account using Brails IP allowlisting, configure the backend source addresses rather than end-user devices. Hosted Supabase Edge Functions do not provide a stable egress address. The proxy supplies the selected calls with a stable network route without requiring the rest of the application to move.
1. Establish the account and route
Record the intended Brails environment, the Supabase project and the QuotaGuard subscription before handling any secrets. This avoids a plausible-looking check against the wrong account.
Use this setup worksheet:
| Item | What the operator records privately |
|---|---|
| Supabase deployment | Project and function revision that will run the check |
| Brails environment | Sandbox for this helper, with an authorized account owner |
| Account networking policy | Whether allowlisting is enabled and who can approve a change |
| QuotaGuard route | Subscription label, selected region and HTTP or HTTPS proxy transport |
| Allowed sources | Both assigned IPv4 addresses and any existing authorized callers |
| Provider acceptance | Brails confirmation of the selected region and shared or dedicated address type |
| Destination reachability | IPv4 connectivity to the sandbox API through the selected route |
Confirm region and address-type acceptance with the account’s administrator or provider contact. A payment destination country does not establish an allowed server location. A dedicated address is not established as a universal Brails requirement by the linked documentation.
The standard QuotaGuard subscription has two source addresses that may carry traffic. Prepare both for the relevant Brails allowlist. When adding entries, preserve any other approved backend callers. Do not replace a working set based only on one echo response.
2. Choose the transport deliberately
Keep the connection URL’s scheme, hostname and port exactly as provided for your subscription. Use the dashboard connection hostname, rather than substituting one of the displayed egress addresses into the proxy URL.
For destination HTTPS, Static uses an HTTP proxy and Shield uses an HTTPS proxy. Both tunnel the destination’s TLS session; Shield also encrypts the application-to-proxy hop. On the plain HTTP hop, the initial proxy authentication and destination metadata are not protected by that additional TLS layer. See QuotaGuard’s HTTPS explanation.
The supplied helper deliberately accepts only HTTP and HTTPS proxy URLs. Its accepted transports are narrower than every transport listed in Deno or the general platform guide. Do not feed it a SOCKS URL, switch http to https by hand, remove certificate validation, or assume an arbitrary custom domain is accepted.
3. Store the three server-side settings
Configure these values in the Supabase project that will execute the diagnostic:
| Name | Required for | Value |
|---|---|---|
QUOTAGUARD_PROXY_URL |
Both modes | Complete credential-bearing dashboard URL for the chosen HTTP or HTTPS proxy |
QUOTAGUARD_EXPECTED_IPS |
Both modes | Exactly two distinct assigned IPv4 addresses, separated by a comma |
BRAILS_SANDBOX_API_KEY |
wallets mode only |
Existing Brails sandbox key the operator is authorized to use |
Supabase’s environment-variable guide covers setting hosted secrets and reading them through Deno.env.get. A local environment file does not by itself configure a hosted function. Keep real environment files out of source control, and avoid commands that place secrets in shell history.
Use separate credentials for separate security boundaries. The proxy username and password authenticate the proxy connection. The Brails key authenticates the API request. The helper sends no Brails authorization header to the echo service.
The account’s two addresses can be stored as configuration, but do not expose even diagnostic outputs through a public endpoint. Put only placeholder values in shared setup files. Keep the complete proxy URL out of error messages, screenshots and support tickets.
4. Add the diagnostic helper
Copy code/brails-check.mjs from this packet to:
supabase/functions/_shared/brails-check.mjs
Import it into an existing operator-only diagnostic function:
import { checkBrailsSandbox } from "../_shared/brails-check.mjs";
The import does not initiate a request or register an HTTP handler. Execute the helper only after the application’s existing authorization logic has established that the caller may run the chosen diagnostic. Merely putting a function behind a URL, a project key or a client-side button is not a substitute for operator authorization.
The implementation uses Deno’s proxy-aware client and supplies it explicitly through the Deno fetch client option. Setting an environment variable alone does not prove a request uses that client. Review each separate SDK or background job that talks to Brails.
The helper makes the diagnostic route narrow:
- Two modes:
echoandwallets. - Two fixed HTTPS destinations, with no caller-controlled target URL.
- An exact expected pair of IPv4 addresses.
- Rejection of proxy URLs outside standard
*.quotaguard.comhosts. - Redirect rejection on both requests.
- A ten-second timeout signal for each request.
- No retry or fallback through a direct connection.
- Consumed echo data and canceled wallet response bodies before client close.
- Stage-only error messages rather than credential-bearing transport details.
The ten-second values are diagnostic budgets chosen by the helper, not provider latency commitments. The two requests are sequential and each gets its own timeout signal. See Deno’s fetch timeout example for the underlying mechanism.
5. Verify the echo route first
From the authorized operator path in the deployed function, run:
const routing = await checkBrailsSandbox("echo");
This mode needs the proxy URL and expected pair but no Brails key. A successful return contains one field:
{"echoEgressIp":"192.0.2.10"}
The address shown here is illustrative, not a QuotaGuard allocation. In a real result, the helper has compared the returned IP against the two configured addresses and found a match.
Record the actual result privately with the deployment revision and time. The result establishes the route observed by the echo service for that request. It does not establish which address a later connection will use, and repeatedly running the echo is not a deterministic failover test.
If it fails, stop before testing Brails. Resolve configuration, transport or echo problems using the troubleshooting guide. Do not temporarily bypass the proxy just to make the diagnostic return successfully.
6. Check authorized sandbox API access
After the echo succeeds, an operator with permission to read that Brails sandbox account can run:
const connectivity = await checkBrailsSandbox("wallets");
This repeats the echo stage and then makes the documented GET /api/v2/wallets request to the sandbox host. It returns only:
{
"echoEgressIp": "192.0.2.10",
"brailsStatus": 200,
"brailsHttpOk": true
}
The status and address above are an illustrative successful shape. The helper discards the wallet response body, including on non-success statuses. It does not return balances, wallet identifiers or provider error bodies.
Read each field at its actual scope:
| Field | Meaning |
|---|---|
echoEgressIp |
Source IP observed by the preceding echo request |
brailsStatus |
HTTP status received from the fixed Brails sandbox URL |
brailsHttpOk |
Whether that status is in the HTTP success range |
A non-2xx Brails response is returned as data with brailsHttpOk: false; it is not automatically thrown as an exception. Transport failures and earlier validation failures throw sanitized stage errors. The calling operator path should handle both cases.
The echo and Brails fetches use separate destination connections. To establish the source Brails observed, use account-side or provider-side evidence tied to the Brails request. HTTP success on this read also leaves payout correctness, transaction state and production readiness to their own checks.
7. Carry the routing pattern into the real integration
Keep the sandbox diagnostic unchanged as a small, understandable check. Review the production application separately:
- Inventory all Brails call sites, including retry workers, scheduled jobs and SDK instances.
- Identify the actual HTTP transport for each. A successful helper does not configure another library automatically.
- Apply the selected proxy-aware client at those call sites without changing unrelated requests.
- Keep the production hostname and key paired correctly. Brails documents separate base URLs.
- Confirm the production account’s source list and acceptance conditions independently from sandbox.
- Retain default TLS and hostname verification, bounded timeouts and controlled error reporting.
- Define rollback as an application deployment/configuration decision. Do not add a silent direct fallback that defeats the approved route.
- Review payment-state recovery independently. Use Brails’ payout workflow documentation, rather than treating this diagnostic as a payout implementation.
The helper does not create payments, beneficiaries, cards or wallets. Keep those operations out of the networking smoke test. A timed-out business request may require reconciliation before any retry; a better network route does not supply those application semantics.
8. Keep a compact operating record
For each deployment check, retain the environment label, revision, UTC time, proxy transport, echo result, Brails status and any provider-side request reference already available to the operator. Store that record in an access-controlled location. Do not add raw authorization headers, a credential-bearing URL, balances or wallet response bodies.
Use the same distinction during support: configuration accepted, echo route observed, sandbox HTTP response received, and destination source confirmed are separate observations. That separation makes failures easier to diagnose and keeps a small routing change from becoming a broader rewrite of the payment application.
Continue with the quickstart, helper reference or troubleshooting.
Download the reference examples · Integration overview