> ## Documentation Index
> Fetch the complete documentation index at: https://partners.ladder.africa/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> From test keys to a live order in five steps. Sandbox and KYB run in parallel.

<Steps>
  <Step title="Ladder creates your organisation and issues test keys">
    You receive a `pk_test_…` key id and a `sk_test_…` secret, first on UAT (`https://api-dev.myladder.africa`) for integration work, then on production once you are ready. The secret is shown once; store it in a secrets manager, never in code or logs.
  </Step>

  <Step title="Complete KYB through the API">
    Business information, directors and owners, documents and a settlement account, then `POST /kyb/submit`. `GET /organisation` lists whatever is still missing. See [KYB](/guides/kyb).
  </Step>

  <Step title="Build against the sandbox">
    With test keys everything settles instantly: fund a wallet and settle it with the sandbox endpoint, place orders, redeem, register a webhook receiver. Nothing here waits for approval.
  </Step>

  <Step title="Approval and live keys">
    Ladder reviews KYB. On approval you receive `pk_live_…` keys. Live keys on an unapproved organisation are refused.
  </Step>

  <Step title="Go live">
    Fund a live wallet on a real rail, place an order, act on `order.completed`. Walk the [go-live checklist](/reference/go-live-checklist) first.
  </Step>
</Steps>

## Your first signed call

<CodeGroup>
  ```python Python theme={null}
  import hashlib, hmac, json, time, uuid
  import requests

  BASE = "https://api.myladder.africa"
  KEY_ID, SECRET = "pk_test_…", "sk_test_…"

  def call(method, path, payload=None, idempotency_key=None):
      body = b"" if payload is None else json.dumps(payload, separators=(",", ":")).encode()
      ts = str(int(time.time()))
      canonical = "\n".join([ts, method.upper(), path, hashlib.sha256(body).hexdigest()])
      signature = hmac.new(SECRET.encode(), canonical.encode(), hashlib.sha512).hexdigest()
      headers = {"X-Ladder-Key": KEY_ID, "X-Ladder-Timestamp": ts,
                 "X-Ladder-Signature": signature, "Content-Type": "application/json"}
      if method.upper() == "POST":
          headers["Idempotency-Key"] = idempotency_key or str(uuid.uuid4())
      return requests.request(method, BASE + path, data=body, headers=headers, timeout=30)

  print(call("GET", "/partner/v1/organisation").json())
  ```

  ```javascript Node.js theme={null}
  const crypto = require("crypto");
  const BASE = "https://api.myladder.africa";
  const KEY_ID = "pk_test_…", SECRET = "sk_test_…";

  async function call(method, path, payload, idempotencyKey) {
    const body = payload === undefined ? "" : JSON.stringify(payload);
    const ts = Math.floor(Date.now() / 1000).toString();
    const bodyHash = crypto.createHash("sha256").update(body).digest("hex");
    const canonical = [ts, method.toUpperCase(), path, bodyHash].join("\n");
    const signature = crypto.createHmac("sha512", SECRET).update(canonical).digest("hex");
    const headers = { "X-Ladder-Key": KEY_ID, "X-Ladder-Timestamp": ts,
                      "X-Ladder-Signature": signature, "Content-Type": "application/json" };
    if (method.toUpperCase() === "POST") headers["Idempotency-Key"] = idempotencyKey || crypto.randomUUID();
    return fetch(BASE + path, { method, headers, body: body || undefined });
  }

  call("GET", "/partner/v1/organisation").then(r => r.json()).then(console.log);
  ```
</CodeGroup>

The response tells you where KYB stands:

```json theme={null}
{
  "data": {
    "id": "3794e63e-9214-4636-927d-9bf5cf137f69",
    "legal_name": "Harbour Point Asset Management Limited",
    "country": "NG",
    "kyb_status": "draft",
    "environment": "test",
    "kyb_missing": [
      "business.entity_type",
      "people: at least one director",
      "documents.certificate_of_incorporation",
      "settlement_accounts: at least one"
    ]
  }
}
```

<Note>
  Sandbox and live are the same host. The key you sign with decides the environment, and every object you create belongs to that environment only.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.