Overview

The Fluveo API is served under the /v1/* path prefix and uses familiar PaymentIntent-style requests and responses, so existing v1-style integrations and compatible tooling work as-is.

Base URL

  • Sandbox: https://api.sandbox.fluveo.dev
  • Production: https://api.fluveo.dev

Authentication

The /v1 API accepts the same secret-key auth schemes declared by Stripe OpenAPI:

SchemeExample
HTTP Basic Authcurl -u sk_test_...:
Bearer AuthAuthorization: Bearer sk_test_...

Docs and runnable examples prefer Basic Auth because that is Stripe’s canonical curl form. Secret keys are server-side credentials: sk_test_... for sandbox and sk_live_... for production. Publishable keys (pk_test_..., pk_live_...) are browser-side keys and are not valid for secret-key server operations. The launch /v1 surface does not accept an api-key header — secret keys are the only supported credential.

Create a key from the dashboard API keys page (it is shown exactly once). See authentication for the full key lifecycle.

$curl https://api.fluveo.dev/v1/payment_intents \
> -u sk_test_...: \
> -d amount=4242 \
> -d currency=usd

Request bodies

Write operations take application/x-www-form-urlencoded bodies, exactly like Stripe. Nested values use bracket syntax — metadata[order_id]=ord_9001 for maps and expand[]=latest_charge for arrays. curl’s -d sets the form content type automatically; use --data-urlencode for values with reserved characters.

$curl https://api.fluveo.dev/v1/payment_intents \
> -u sk_test_...: \
> -d amount=4242 \
> -d currency=usd \
> --data-urlencode 'metadata[order_id]=ord_9001' \
> -d 'expand[]=latest_charge'

Unsupported or internal fields are rejected with an invalid_request_error that names the offending param. Public responses use Stripe object and field names (id, object, customer, payment_intent) and never leak internal identifiers.

Idempotency

Add an Idempotency-Key header to safely retry a request. Fluveo caches the response for 24 hours and returns the cached response on duplicate keys — matching the retry semantics developers expect from familiar payment APIs.

$curl https://api.fluveo.dev/v1/payment_intents \
> -u sk_test_...: \
> -H "Idempotency-Key: $(uuidgen)" \
> -d amount=4242 \
> -d currency=usd

Versioning

The v1 surface is pinned to a curated, machine-checked launch contract. The current upstream compatibility baseline is Stripe API 2026-05-27.dahlia. Breaking shape changes require a public versioning decision and a deprecation period. Additive fields ship without a version bump only when they preserve Stripe semantics.

Errors

Errors return v1-compatible JSON:

1{
2 "error": {
3 "type": "invalid_request_error",
4 "code": "amount_too_small",
5 "message": "Amount must be at least 50",
6 "param": "amount"
7 }
8}

Error type values:

  • api_error — Fluveo internal error (5xx)
  • invalid_request_error — your request was malformed (4xx)
  • authentication_error — your API key is missing or invalid
  • card_error — the customer’s card was declined or rate-limited
  • idempotency_error — Idempotency-Key conflict
  • rate_limit_error — too many requests

External card vault (VGS outbound proxy)

Browser card entry uses VGS Collect so PAN/CVC is collected outside Fluveo. Fluveo surfaces only receive VGS aliases (for example, tok_sandbox_xxxx), and reject real card numbers or security codes.

When the router calls a PSP, egress goes through the VGS outbound proxy. VGS reveals the aliases to card data only at the boundary toward the PSP. This flow is PSP-agnostic; the current development/sandbox PSP is Stripe sandbox.

Webhooks

Register webhook endpoints under /v1/webhook_endpoints — each with its own whsec_... secret and an enabled_events filter (exact event types or the * wildcard) — and browse recorded events under /v1/events. Deliveries are signed HMAC-SHA256 and carry a Fluveo-branded Fluveo-Signature header alongside a compatibility Stripe-Signature header, so existing webhook verification code keeps working while keeping Fluveo as the product surface. Endpoint management, the signature contract, and signed delivery are live today — a triggered event fans out to every subscribed endpoint, each POST signed with that endpoint’s own secret. See Webhooks and the event types catalog.

Endpoint reference

Every live endpoint is documented in the API Reference, generated directly from the canonical OpenAPI contract. For which resources are live versus not yet implemented, see API coverage.