Changelog

Changelog

Every version of the AdProMaxPay API, what it holds, and whether it breaks existing code.

Open as Markdown

This page lists every version of the API, newest first. Each entry says whether it is breaking: whether code written for the version before it must change.

How versions work

  • A version is named by its date: 2026-11-01.
  • Your organization is pinned to the version that was current when it was created. Its api_version, in GET /v1/account, names it. Your requests use it unless they say otherwise.
  • A request can name a version with the X-AdProMaxPay-Version header. An unknown version is refused with 400, api_version_invalid.
  • Every event carries the api_version it was written with.

A breaking change comes in a new dated version, and the version you are pinned to keeps working as it did. Additions come without a new version: new objects, new fields, new event types, new optional parameters and new error codes. Write your code to ignore the fields and the event types it does not know.

  • curl
  • Node.js
  • TypeScript
  • Python
  • PHP
  • Ruby
  • Go
  • Java
  • C#
  • Rust
version.mjsversion.tsversion.pyversion.phpversion.rbversion.goVersion.javaVersion.csmain.rs
curl https://pay-api.adpromax.com/v1/account \
  -u "$APX_SECRET_KEY:" \
  -H "X-AdProMaxPay-Version: 2026-11-01"
const response = await fetch('https://pay-api.adpromax.com/v1/account', {
  headers: {
    'Authorization': `Bearer ${process.env.APX_SECRET_KEY}`,
    'X-AdProMaxPay-Version': '2026-11-01',
  },
})
const account = await response.json()
console.log(account.api_version)
interface Account {
  id: string
  object: 'account'
  api_version: string
}

const response = await fetch('https://pay-api.adpromax.com/v1/account', {
  headers: {
    'Authorization': `Bearer ${process.env.APX_SECRET_KEY}`,
    'X-AdProMaxPay-Version': '2026-11-01',
  },
})
const account = (await response.json()) as Account
console.log(account.api_version)
import os

import requests

response = requests.get(
    "https://pay-api.adpromax.com/v1/account",
    auth=(os.environ["APX_SECRET_KEY"], ""),
    headers={"X-AdProMaxPay-Version": "2026-11-01"},
)
account = response.json()
print(account["api_version"])
<?php
$ch = curl_init('https://pay-api.adpromax.com/v1/account');
curl_setopt_array($ch, [
    CURLOPT_USERPWD => getenv('APX_SECRET_KEY') . ':',
    CURLOPT_HTTPHEADER => ['X-AdProMaxPay-Version: 2026-11-01'],
    CURLOPT_RETURNTRANSFER => true,
]);
$account = json_decode(curl_exec($ch), true);
echo $account['api_version'], PHP_EOL;
require 'json'
require 'net/http'

uri = URI('https://pay-api.adpromax.com/v1/account')
request = Net::HTTP::Get.new(uri)
request.basic_auth(ENV.fetch('APX_SECRET_KEY'), '')
request['X-AdProMaxPay-Version'] = '2026-11-01'

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(request)
end
account = JSON.parse(response.body)
puts account['api_version']
package main

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

type Account struct {
	ID         string `json:"id"`
	APIVersion string `json:"api_version"`
}

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://pay-api.adpromax.com/v1/account", nil)
	if err != nil {
		log.Fatal(err)
	}
	req.SetBasicAuth(os.Getenv("APX_SECRET_KEY"), "")
	req.Header.Set("X-AdProMaxPay-Version", "2026-11-01")

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

	var account Account
	if err := json.NewDecoder(res.Body).Decode(&account); err != nil {
		log.Fatal(err)
	}
	fmt.Println(account.APIVersion)
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Version {
    public static void main(String[] args) throws Exception {
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://pay-api.adpromax.com/v1/account"))
            .header("Authorization", "Bearer " + System.getenv("APX_SECRET_KEY"))
            .header("X-AdProMaxPay-Version", "2026-11-01")
            .GET()
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());

        // The JDK has no JSON parser: a small regex reads api_version.
        Matcher version = Pattern
            .compile("\"api_version\"\\s*:\\s*\"([^\"]*)\"")
            .matcher(response.body());
        System.out.println(version.find() ? version.group(1) : response.body());
    }
}
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;

var json = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower };
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("APX_SECRET_KEY"));
http.DefaultRequestHeaders.Add("X-AdProMaxPay-Version", "2026-11-01");

var account = await http.GetFromJsonAsync<Account>("https://pay-api.adpromax.com/v1/account", json);
Console.WriteLine(account!.ApiVersion);

record Account(string Id, string ApiVersion);
// Cargo.toml: reqwest = { version = "0.12", features = ["blocking", "json"] }
//             serde = { version = "1", features = ["derive"] }
use serde::Deserialize;

#[derive(Deserialize)]
struct Account {
    api_version: String,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let account: Account = reqwest::blocking::Client::new()
        .get("https://pay-api.adpromax.com/v1/account")
        .bearer_auth(std::env::var("APX_SECRET_KEY")?)
        .header("X-AdProMaxPay-Version", "2026-11-01")
        .send()?
        .json()?;
    println!("{}", account.api_version);
    Ok(())
}

2026-11-01

Not breaking: the first version of the API. It holds:

  • The account: GET /v1/account, your organization and its activation status. See Your API keys.
  • Payment intents and charges, by card and in cash, with their statuses and attempts. See How payments work.
  • Checkout sessions, for the hosted payment page. See Hosted checkout.
  • Customers. See Customers.
  • Refunds of card payments. See Refunds.
  • Events and webhook endpoints: signed deliveries, retried for about three days. See Webhooks.
  • Test helpers, in test mode only. See Test helpers API.
  • Idempotency: required on the requests that move money, answers kept 24 hours. See Idempotency.
  • Errors in seven types, with messages in French, English or Arabic, from the Accept-Language header. See Handling errors.
  • Cursor pagination on lists: limit, starting_after and ending_before.
  • Rate limits per organization and mode, with the RateLimit-* headers. See Rate limits.
  • Metadata on payment intents, checkout sessions, customers, refunds and webhook endpoints. See Metadata.