General Liquidity
Start

Quickstart

A first payment, from nothing to a receipt, in one request.

Install

Pick whichever client matches what you already write. Every one of them is generated from the same specification, so the shape below is the same shape everywhere.

TypeScript
# not on npm yet: install from the repository
bun add github:general-liquidity/general-liquidity-typescript
Go
go get github.com/general-liquidity/general-liquidity-go/client

Make a payment

A payment is a signed instruction: a payee, an amount, a purpose, the terms it is being made under, and the delegation it is being made beneath. You sign it, the gate decides, and on allow it settles.

TypeScript
import { createClient } from "@general-liquidity/sdk";

// The client takes no credential. It signs instructions with your signer.
const gl = createClient({ baseUrl, signer });

const receipt = await gl.pay({
  idempotencyKey: "",              // left blank, the client mints one
  payee:   "compute.example",
  amount:  { value: "420000", asset: "USDC" },
  purpose: "inference, batch 41",
  terms: {
    rail:          "x402",
    reversibility: "irreversible",
    finality:      "instant",
    credential:    "http-sig",
    capitalSource: "payer",
    presence:      "delegated",
  },
  envelope,                        // identity, mandate, and the operator's grant
});

console.log(receipt.reference);
HTTP
curl -X POST https://api.generalliquidity.com/pay \
  -H "Authorization: Bearer $GL_API_KEY" \
  -H "Idempotency-Key: 8f14e45f-ea1b-4c1f-9f04-2c0a1c7e0b21" \
  -H "Content-Type: application/json" \
  -d @intent.json

The terms are required and never silently defaulted. They are the fields the decision reasons over, and guessing them for you is how a system ends up making an irreversible payment because nobody said it should not.

Handle every outcome

A payment does not simply work or fail. It settles, it waits for a person, or it is refused. Money settles on a 200 and nowhere else, and everything that is not a settlement is raised as a typed error rather than returned as a half-receipt.

TypeScript
import { ApprovalPendingError, DeniedError } from "@general-liquidity/sdk";

try {
  const receipt = await gl.pay(intent);   // settled
} catch (err) {
  if (err instanceof ApprovalPendingError) {
    // Nothing moved. A person has to approve it.
  } else if (err instanceof DeniedError) {
    // Refused, with reasons. Do not retry the same instruction.
  }
}

Send it once

Pass an Idempotency-Key header on every payment. If the same key arrives twice you get the original answer back rather than a second payment. Agents retry, networks fail halfway, and this is the difference between a duplicate charge and a duplicate request.

HTTP
-H "Idempotency-Key: 8f14e45f-ea1b-4c1f-9f04-2c0a1c7e0b21"

Then what

Read concepts for the vocabulary, decisions for what each outcome commits you to, and limits for the mandate this payment is checked against.