Menu

Blaya Developers

Download the OpenAPI 3.1 contract

API V1 · version 2026-09-18 · sandbox

Add secure freelance payments to your software — free. The buyer pays a 3% fee including tax and the freelancer receives 100% of their service amount. Payment takes place on Blaya’s hosted checkout.

Open my sandbox

An executable example

Download the Node.js quickstart

Requires Node.js 24.19 or later. Set BLAYA_BASE_URL, BLAYA_TEST_KEY and BLAYA_FREELANCER_EMAIL in your private server environment, then run node partner-quickstart.mjs. Never include the key in your frontend. Optional BLAYA_EXTERNAL_REFERENCE and BLAYA_FREELANCER_REFERENCE must remain stable when retrying.

The first run invites the freelancer. After sign-in, MFA and consent, the next run creates a fictional €100 request and reads its persisted status. It does not charge a card. If the provider or KYC blocks test payment, that restriction remains visible: do not force the status.

1. Server authentication

Create a key with recent MFA. It is displayed only once. Store it in your secret manager. Limit its scopes; create a new key and revoke the old one to rotate it.

Authorization: Bearer $BLAYA_TEST_KEY
Blaya-Version: 2026-09-18
Content-Type: application/json
Idempotency-Key: unique-operation-id

120 requests per minute per partner. Keys only work in their own environment. Live keys are unavailable.

2. Invite a freelancer

POST /api/v1/freelancers
{"email":"freelancer@example.invalid","external_reference":"vendor-42","locale":"fr"}

Scope freelancers:write. GET /api/v1/freelancers/{id} returns the current invitation status. Save the returned id and onboarding_url. The freelancer signs in or registers with this verified email and authorizes your software in Integrations. No additional Stripe account is created. An invitation does not prove account existence or completed KYC.

3. Create a payment request

POST /api/v1/payment-requests
{"freelancer_id":"UUID_FROM_STEP_2","amount":10000,"currency":"EUR","description":"Website design","external_reference":"invoice-104","locale":"fr"}

Scope requests:write. Integer cents: 10000 = €100. Redirect the browser to checkout_url, without an iframe. Checkout verifies beneficiary, KYC, limits, fees and bank authentication using the shared engine. A created request or browser return never proves payment.

GET /api/v1/payment-requests/{id}

Scope requests:read. Read payment_state and release_state. A confirmed transfer is not a confirmed bank payout. J7/J30 deadlines start at capture.

Optional client context

You may add client: {name, email, reference?} when creating a request. This context is encrypted and visible only to the freelancer in their private workspace. It does not verify the payer, does not prefill an email treated as verified, triggers no charge, and is never included in webhooks. The client confirms their own information at checkout.

4. Private documents

Scope documents:write. POST /api/v1/documents sends PDF/JPEG/PNG bytes (maximum 10 MiB) with Content-Type, X-Freelancer-ID, X-Document-ID (UUID), X-Document-Batch (UUID), URI-encoded X-File-Name and Idempotency-Key.

Poll GET /api/v1/documents/{id}. Wait for clean then POST {"action":"confirm"} to the same endpoint. Add document_ids when creating the request (maximum 3). A scan failure preserves quarantine; action retry allows bounded recovery. You can only inspect the status of your own uploads, never the freelancer’s pre-existing private documents.

5. Signed webhooks

In the partner dashboard, configure a public HTTPS URL using recent MFA. The signing secret is displayed once and rotates on each save. Configure your receiver before resuming delivery. Private endpoints, URL query strings, redirects and ports other than 443 are rejected.

Blaya-Signature: t=TIMESTAMP,v1=HEX_HMAC_SHA256
Blaya-Event-ID: UUID

HMAC input = TIMESTAMP + "." + RAW_REQUEST_BODY

Verify the signature in constant time, reject timestamps more than 300 seconds away, then deduplicate the event ID. Return 2xx after durable storage, before slow processing. A 3xx response is a failure. Do not infer event order from arrival order; GET /api/v1/payment-requests/{id} returns current state.

payment.created · payment.captured · release.scheduled · release.extended · claim.opened · claim.resolved · transfer.completed · refund.completed

GET /api/v1/events/{id} (events:read scope) returns the event body. No documents, customer emails, KYC data or PSP identifiers are included. The dashboard provides testing, inspection, pause, rotation and redelivery with MFA. Redelivery preserves the event ID and raw body.

Up to 8 automatic attempts per series, delayed by 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 12 hours then 24 hours. After 8 consecutive failures, the endpoint is disabled and its administrator is notified. A timeout remains unknown. Manual redelivery is bounded to 40 total attempts per event/endpoint. In mock mode a local receiver verifies the signature; no external HTTPS delivery is claimed.

Idempotency and errors

Keep a stable key per write and retry with exactly the same data after timeout. Reusing a key with different content returns 409. external_reference is unique per partner. Responses expose no PSP keys, KYC data or raw documents.

  • 401 invalid_api_key
  • 403 api_key_or_scope_invalid
  • 404 not_found
  • 409 idempotency_conflict / freelancer_onboarding_required / document_not_ready
  • 422 invalid_input / total_limit
  • 429 rate_limited
  • 503 provider_unavailable

Use the machine code and requestId for support. Never log Authorization headers or document bodies.

Test scenarios

  1. Repeat a request with the same key: one identifier; a changed payload must return 409.
  2. Revoke a key and verify new calls are rejected. Remove software consent as the freelancer: new requests are blocked while existing ones remain trackable.
  3. Send a test event from the dashboard, verify its signature and deduplication, then test an HTTP rejection and retry. Redelivery preserves the event.
  4. With an eligible test payment account, complete checkout, bank authentication and the client timeline. Verify capture, extension, claim and resolution through their authorized flows. Isolated server tests cover deadline races; no partner API can change the clock or force a transfer.

Changelog

2026-09-18 · V1 sandbox

First public contract: invitations and consent, requests and private files, statuses, optional client context, signed events and dashboard. Unrecognized versions return an error; this version issues no live keys.