API documentation
REST API for hire-yard operations.
Cognito JWT auth, resource-oriented endpoints, JSON in / JSON out (plus CSV for the tax export). API access ships with the Pro tier ($379 AUD / month). Sandbox available for development against your trial tenant — no separate environment to set up.
Quickstart
- 1. Sign in. The API uses the same Cognito user pool as the web app. Sign in via the /counter/ flow and pull the JWT from your session, or use the AWS Cognito SDK directly with
InitiateAuth. - 2. Pick the right base URL. Tenants are region-pinned at signup based on the email TLD (.com.au → ap-southeast-2, .co.nz → ap-southeast-6, .co.uk → eu-west-2, etc.). Use the base URL for your region — cross-region requests work but add latency.
- 3. Send the JWT in the Authorization header.
Authorization: Bearer <id_token>. The token's custom claims (tenantId, role, homeRegion) gate access to every endpoint automatically.
# Example: list your assets (curl)
curl https://api-syd.yardguild.com/assets \
-H "Authorization: Bearer $YG_TOKEN"
# Example: seed your starter library
curl -X POST https://api-syd.yardguild.com/assets/seed \
-H "Authorization: Bearer $YG_TOKEN" \
-H "Content-Type: application/json" \
-d '{"vertical":"tools","country":"AU"}'
# Example: create a contract
curl -X POST https://api-syd.yardguild.com/contracts \
-H "Authorization: Bearer $YG_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"renter": {"name":"Acme Builders", "email":"j@acme.com.au"},
"items": [{"asset_id":"abc-123","daily_rate":70}],
"due_back_at": "2026-06-02T17:00:00+10:00"
}'Base URLs (per region)
Tenants are region-pinned. Your home region is in the custom:homeRegion claim of your JWT.
| Region | AWS region code | Base URL |
|---|---|---|
| Australia (Sydney) | ap-southeast-2 | https://api-syd.yardguild.com |
| New Zealand (Auckland) | ap-southeast-6 | https://api-akl.yardguild.com |
| United Kingdom (London) | eu-west-2 | https://api-lon.yardguild.com |
| Ireland (Dublin) | eu-west-1 | https://api-dub.yardguild.com |
| Canada (Montréal) | ca-central-1 | https://api-yul.yardguild.com |
| United States (N. Virginia) | us-east-1 | https://api-iad.yardguild.com |
Custom-domain mappings ship after the first paying tenant in each region. Until then, use the raw API Gateway URL from /counter/settings.
Conventions
- JSON in, JSON out. Send
Content-Type: application/jsonon POST / PUT / PATCH. Errors return{ "code": "...", "message": "..." }. Exceptions: CSV endpoints returntext/csv, presign endpoints return the upload URL. - Tenant isolation by construction. Every endpoint scopes by the
custom:tenantIdclaim. You cannot read another tenant's data — even a misformed query falls back to your tenant. - Errors are predictable.
401missing/invalid JWT ·403role insufficient ·404resource not found ·409conflict (e.g. illegal state transition) ·422validation error (per-field details inerrors[]) ·429rate-limited ·5xxserver error (retry with backoff). - Rate limit: 50 req/sec per tenant. Burst of 100. Hits return
429withRetry-Afterheader. Email us if you need more — usually we'll just raise it. - Idempotency. POST endpoints accept an optional
Idempotency-Keyheader; we deduplicate for 24 hours. The PayPal webhook ingestion is idempotent by design (event ID stored in DDB for 90-day TTL). - No payment processing on renters. The Bonds endpoints record payment details (method / reference / ID-sighted / photos) but never charge anything. The money flow stays with your existing processor — cash, EFTPOS, Square, your own PayPal Business or Stripe, etc. The only place YardGuild processes a payment is your monthly Pro-tier subscription via
/billing/subscribe.
Endpoints
All endpoints require a Cognito JWT in the Authorization header unless otherwise noted. The handful of public endpoints (waiver renter flow, PayPal webhook, health) carry their own auth mechanism (token, signature, or none).
Tenant
Read or update the tenant profile (yard name, country, ABN/NZBN, alert email, GST flag, custom claims). The tenant is derived from the JWT — you can only access your own.
- GET
/tenant/meFetch the authenticated tenant's profile.
- PUT
/tenant/meUpdate tenant profile. Body: partial TenantMeta (name, country, timezone, abn_or_nzbn, alert_email, gst_registered).
Assets
Inventory items. Each asset has a name, category, optional size code (e.g. SKI_BOOT_MP28_5), daily rate, default bond, condition state, and photo URL. CSV import/export is supported for bulk operations.
- GET
/assetsList all assets for the tenant. Returns paginated array.
- POST
/assetsCreate a single asset. Body: Asset (without asset_id; the server assigns).
- POST
/assets/importBulk CSV import. Body: multipart/form-data with file= field. Returns { created, failed }.
- GET
/assets/exportBulk CSV export. Returns text/csv with all tenant assets.
- POST
/assets/seedSeed starter library. Body: { vertical: "tools"|"party"|"ski", country: "AU"|"NZ"|"UK"|"IE"|"CA"|"US" }. Returns { templates, assets } counts.
- GET
/assets/templatesList available starter templates for the tenant's vertical + country (without creating them).
Contracts
Rental contracts move through states: RESERVED → CHECKED_OUT → RETURNED → SETTLED. Each contract has line items (assets), a renter (name + contact), and optional bond + waiver records.
- GET
/contractsList contracts. Query params: status, since, limit.
- POST
/contractsCreate a contract. Body: { renter, items[], due_back_at }.
- POST
/contracts/{id}/{action}Transition the contract. action ∈ { check-out, check-in, settle, cancel }. Body validates state-transition.
- POST
/contracts/{id}/photo/presignGet a presigned S3 PUT URL for uploading a condition photo. Body: { filename, content_type }. Returns { upload_url, photo_url, expires_at }.
Bonds (manual tracking — we don't process renter payments)
Bonds are recorded on the contract with payment method, reference, ID sighted, and evidence photos. The money flow stays with whichever processor you used (cash / EFTPOS / Square / your own PayPal / Stripe / Moneris). YardGuild only keeps the records.
- POST
/contracts/{id}/bondRecord a new bond. Body: { amount, currency, payment_method, reference_number, id_sighted_type, id_sighted_number, evidence_photos[] }.
- GET
/contracts/{id}/bondList all bond records on the contract.
- POST
/contracts/{id}/bond/{depositId}/captureMark a bond captured (damage). Body: { amount?, reason }. Set amount < bond_amount for partial-capture.
- POST
/contracts/{id}/bond/{depositId}/voidMark a bond released (clean return). Body: { reason? }.
Waivers
Waivers use a magic-link flow: staff starts the waiver (protected), the renter receives a token URL, the renter views (public) and signs (public, token-auth). Signed PDFs are stored in S3 with PII redacted from logs.
- POST
/waiver/startStaff: start a waiver for a renter. Body: { contract_id, renter_email, renter_phone }. Returns { token, magic_url, expires_at }.
- GET
/waiver/{token}Token-authRenter: fetch waiver content for signing. Public — token-authed.
- POST
/waiver/{token}/signToken-authRenter: submit signature + identity. Public — token-authed. Body: { name, signature_base64, ip_seen }.
Reports
Read-only aggregations over the tenant's data. All return JSON; the GST/BAS export returns CSV in your country's accounting format.
- GET
/reports/todayToday's overdue + due-back + cash-flow snapshot.
- GET
/reports/cash-flowCash flow per day for the last 30 days.
- GET
/reports/asset-utilizationUtilization % per asset for the last 30 days.
- GET
/reports/revenue-per-assetRevenue per asset for the last 30 days.
- GET
/reports/top-rentersTop 20 renters by contract count + revenue.
- GET
/reports/damage-rateDamage rate per category over the last 90 days.
- GET
/reports/seasonalSeasonal demand trend per category.
- GET
/reports/waiver-complianceAudit: every rental cross-referenced with a signed waiver record.
- GET
/reports/gst-export.csvTax-CSV export. Query: since=YYYY-MM-DD, until=YYYY-MM-DD. Format adapts to tenant country (ATO BAS / IRD / HMRC VAT / etc.). Returns text/csv.
Billing (your YardGuild subscription)
Manage your monthly subscription to YardGuild. This is the only place PayPal touches our system — renter payments are out-of-band (see Bonds).
- POST
/billing/subscribeStart a PayPal subscription for a tier. Body: { tier: "solo"|"counter"|"multi_yard"|"pro" }. Returns { approval_url } — redirect to it to complete.
- GET
/billing/statusCurrent subscription status. Returns { subscription_tier, subscription_status, current_period_end, approval_url }.
Health
Liveness check — useful for smoke-testing a deploy or monitoring uptime.
- GET
/healthPublicReturns { status: "ok", region, deployed_at }. Public, no auth.
Official SDK?
Not yet. The API is stable and curl/fetch is enough for everything on this page. We'll ship a TypeScript SDK once we have 5+ paying Pro tenants asking for it — until then, the TS types in our web client (web/src/lib/api.ts in the repo) are the closest thing to a typed reference. Copy them into your own project if it helps.
Need an integration we don't have today (Xero, MYOB, QuickBooks, Zapier)? Email hello@yardguild.com — we ship integrations based on paying-tenant demand.
Webhooks
We receive PayPal subscription webhooks at /webhooks/paypal (signature-verified, idempotent — see Bonds note about event-ID-keyed DDB rows with 90-day TTL).
Outbound webhooks (notify your system on contract state changes, bond captures, etc.) are on the roadmap. Email us if this is the integration you need — we'll prioritise it.
Need API access?
Pro tier ($379 AUD / month) includes API access, custom waiver templates, and priority chat. 30-day free trial — the API works against your trial tenant from day one.