Armada Armada API v2

SDKs & CLI

Four official clients — Node, PHP, Go, and a command-line tool — generated from the same OpenAPI spec and each wrapped with hand-rolled HMAC signing. All install straight from GitHub; no package registry accounts needed.

Pick your stack

Node / TypeScript

Repo ↗

@armada/sdk

Typed resource methods, axios-powered, HMAC signing via a request interceptor.

npm i github:armadadelivery/armada-node#v0.1.0-beta.0

armada/sdk

Guzzle-based, Psr-7 friendly, HMAC signing via a Guzzle middleware.

composer config repositories.armada vcs https://github.com/armadadelivery/armada-php
composer require armada/sdk:dev-main

github.com/armadadelivery/sdk-go

net/http based, context-aware, zero third-party deps, RateLimit on every *Response.

go get github.com/armadadelivery/sdk-go@v0.1.0-beta.0

@armada/cli

Single binary (armada). Wraps the Node SDK — every command mirrors a method.

npm i -g github:armadadelivery/armada-cli#v0.1.0-beta.0

What every SDK does for you

  • HMAC signing. You never compute a signature by hand — each SDK injects x-armada-timestamp and x-armada-signature on every request via an interceptor / middleware.
  • Base URL defaults. Sandbox by default. Flip by passing the production baseUrl explicitly — hard to ship to prod by accident.
  • Rate-limit headers. Exposed on every successful response (response.rateLimit in Node, rateLimitFor($res) in PHP, resp.RateLimit in Go). Ignore them if you like; they're there when you need to back off.
  • Typed errors. 4xx/5xx surface with the server's error code + message so your catch blocks can branch.

Node / TypeScript

Typed resource methods under armada.{deliveries,branches,wallet,invoices}. Every call returns { data, status, rateLimit }. Needs Node ≥ 18.

import { ArmadaClient } from '@armada/sdk';

const armada = new ArmadaClient({
  apiKey: process.env.ARMADA_API_KEY!,
  apiSecret: process.env.ARMADA_API_SECRET!,
});

// Every method returns { data, status, rateLimit }
const { data: order } = await armada.deliveries.create({
  reference: 'abc-123',
  payment: { amount: 5, type: 'paid' },
  origin_format: 'branch_format',
  origin: { branch_id: 'YOUR_BRANCH_ID' },
  destination_format: 'location_format',
  destination: { contact_name: 'X', contact_phone: '+965', latitude: 29.3, longitude: 47.9 },
});

// Errors come back as ArmadaError with .status, .code, .response
try {
  await armada.deliveries.retry(order.id);
} catch (err) {
  if (err.status === 409) console.log('Not retryable:', err.response?.message);
  else throw err;
}

PHP

Thin Guzzle wrapper. You build the request path + body; the SDK signs and sends. Returns a PSR-7 ResponseInterface so you drop in any Guzzle middleware you already have. Needs PHP ≥ 8.1.

use Armada\SDK\ArmadaClient;

$armada = new ArmadaClient([
    'apiKey' => getenv('ARMADA_API_KEY'),
    'apiSecret' => getenv('ARMADA_API_SECRET'),
]);

$res = $armada->postJson('/v2/deliveries', $body);
if ($res->getStatusCode() >= 400) {
    $err = json_decode((string) $res->getBody(), true);
    throw new RuntimeException("armada {$res->getStatusCode()}: {$err['message']}");
}
$order = json_decode((string) $res->getBody(), true);

Go

net/http-based, zero third-party deps, everything takes a context.Context. DecodeJSON is a one-liner that errors on 4xx/5xx with the decoded body.

c := armada.NewClient(armada.Options{
    APIKey:    os.Getenv("ARMADA_API_KEY"),
    APISecret: os.Getenv("ARMADA_API_SECRET"),
})

resp, err := c.PostJSON(ctx, "/v2/deliveries", body)
if err != nil { return err }

var order struct{ ID, Status string }
if err := armada.DecodeJSON(resp, &order); err != nil {
    // DecodeJSON returns an error with the status + body for 4xx/5xx
    return err
}

CLI

armada — single binary, built on top of the Node SDK. Every command mirrors a resource method. Credentials live in ~/.armada/config.json (mode 600) or the ARMADA_API_KEY + ARMADA_API_SECRET env vars (env takes precedence).

# first-time setup
armada config set          # prompts for apiKey + apiSecret

# wallet
armada wallet

# branches
armada branches list
armada branches create --from-file branch.json
armada branches get <id>
armada branches update <id> --from-file branch.json
armada branches delete <id>

# deliveries
armada deliveries create --from-file order.json
armada deliveries get <id>
armada deliveries cancel <id> --reason "customer changed mind"
armada deliveries retry <id>
armada deliveries estimate --from-file estimate.json

# invoices
armada invoices list --status paid --since 2026-01-01 --per-page 50
armada invoices get <id>

# switch target
armada --api-base https://api.armadadelivery.com wallet   # prod
armada --json wallet                                      # stdout-only JSON (pipeable)

Versioning & upgrades

Every SDK tracks the OpenAPI spec through an automated sync — when the spec changes in the api repo, the SDK repo gets a regeneration PR within six hours. Maintainers review, merge, and cut a new tag.

Pinning recommendation:

  • Production: pin to a specific tag (#v0.1.0-beta.0). Bump intentionally.
  • Staging / internal tools: pin to a tag or track main — your call.
  • Exploration: just use main. You'll always have the latest.