SpareSpare Docs
GuidesAPI Reference
Quick Start

Quick Start Setup

Create API credentials, configure webhooks, and authenticate, the same steps for every use case.

Every integration, payments, account information, or verification, starts the same way: create credentials, configure a webhook endpoint, and authenticate. Nothing here is specific to one market or product.

Before you start

You will need a Spare sandbox account. If you haven't signed up yet, request access from Spare before continuing.

Create API credentials

  1. Sign in to the Spare Dashboard with your sandbox account.
  2. Open Developers β†’ Applications and create a new application (or select an existing one).
  3. Copy the generated App ID and API key, the key is shown once, so store it in a secrets manager or .env file immediately.
  4. Note your tenant, the regulatory jurisdiction your requests should route to. This is set per request, not fixed to your account.

Keep credentials server-side

Keep your API key off mobile apps and browser code. Authenticate from your backend only.

Depending on your account's structure, a new application request may need approval from an owner or admin, or be auto-approved if you're the only member.

Configure a webhook endpoint

Webhooks are managed in the same Developers section of the dashboard:

  1. Add the URL your server exposes to receive event notifications.
  2. Toggle the webhook active once your endpoint is ready to receive traffic.
  3. Choose which event permissions to subscribe to.

This lets you react to state changes in real time instead of polling. See Webhooks for the event catalog and signature verification.

Set environment variables

export SPARE_APP_ID="your-app-id"
export SPARE_API_KEY="your-api-key"
export SPARE_TENANT="your-tenant"

Authenticate

Exchange your credentials for a short-lived access token, then include it on every subsequent request. The endpoint and headers differ by market, set your market with the country selector in the sidebar.

curl -X POST https://api.sandbox.tryspare.ae/auth/api-keys/sessions \
  -H "x-tenant: UAE" \
  -H "app-id: $SPARE_APP_ID" \
  -H "x-api-key: $SPARE_API_KEY"
const res = await fetch(
  "https://api.sandbox.tryspare.ae/auth/api-keys/sessions",
  {
    method: "POST",
    headers: {
      "x-tenant": "UAE",
      "app-id": process.env.SPARE_APP_ID!,
      "x-api-key": process.env.SPARE_API_KEY!,
    },
  },
);

const { accessToken, expiresIn } = await res.json();
import os
import requests

res = requests.post(
    "https://api.sandbox.tryspare.ae/auth/api-keys/sessions",
    headers={
        "x-tenant": "UAE",
        "app-id": os.environ["SPARE_APP_ID"],
        "x-api-key": os.environ["SPARE_API_KEY"],
    },
)

data = res.json()
access_token = data["accessToken"]
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.sandbox.tryspare.ae/auth/api-keys/sessions"))
    .header("x-tenant", "UAE")
    .header("app-id", System.getenv("SPARE_APP_ID"))
    .header("x-api-key", System.getenv("SPARE_API_KEY"))
    .POST(HttpRequest.BodyPublishers.noBody())
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

// Parse the JSON response and read the accessToken field
JsonNode data = new ObjectMapper().readTree(response.body());
String accessToken = data.get("accessToken").asText();
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

using var client = new HttpClient();

var request = new HttpRequestMessage(
    HttpMethod.Post,
    "https://api.sandbox.tryspare.ae/auth/api-keys/sessions");
request.Headers.Add("x-tenant", "UAE");
request.Headers.Add("app-id", Environment.GetEnvironmentVariable("SPARE_APP_ID"));
request.Headers.Add("x-api-key", Environment.GetEnvironmentVariable("SPARE_API_KEY"));

var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();

using var doc = JsonDocument.Parse(body);
var accessToken = doc.RootElement.GetProperty("accessToken").GetString();
package main

import (
	"encoding/json"
	"net/http"
	"os"
)

req, err := http.NewRequest(
	http.MethodPost,
	"https://api.sandbox.tryspare.ae/auth/api-keys/sessions",
	nil,
)
if err != nil {
	panic(err)
}

req.Header.Set("x-tenant", "UAE")
req.Header.Set("app-id", os.Getenv("SPARE_APP_ID"))
req.Header.Set("x-api-key", os.Getenv("SPARE_API_KEY"))

res, err := http.DefaultClient.Do(req)
if err != nil {
	panic(err)
}
defer res.Body.Close()

var data struct {
	AccessToken string `json:"accessToken"`
	ExpiresIn   int    `json:"expiresIn"`
}
json.NewDecoder(res.Body).Decode(&data)

accessToken := data.AccessToken

Use the returned accessToken on subsequent calls, e.g. discovering providers:

curl "https://api.sandbox.tryspare.ae/providers?countryCode=AE" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "x-tenant: UAE"

Tokens expire, refresh via POST /auth/api-keys/sessions/refresh before they do, or on a 401.

Key takeaways

  • Credentials, webhooks, and authentication work the same regardless of what you're building.
  • The tenant value is a request parameter, not an account-level setting, it determines which regulatory context you're operating in.
  • Store the API key once, server-side, and never re-request it, it's shown only at creation time.

On this page