Monthly lien-law newsletter
Deadline changes, notice pitfalls, and the plays that get contractors paid.
Free WebinarSept 17, 2026 @ 12:00 PM ET
v1 · Public API · HMAC Webhooks

Wire your CRM into All American Notice.

Push preliminary notices, liens, and bond claims programmatically. Get real-time status via signed webhooks. Build against a free sandbox — no postage, no charges.

Heads up: the Postman collection is a .json file — open it in Postman → File → Import (not your PDF reader). The "Run in Postman" button above skips the download and imports it directly.

Sandbox by default
Keys prefixed aan_test_ generate real PDFs but skip postage, Stripe, and Lob.
HMAC-signed events
Every webhook is signed t=ts,v1=sha256(secret, ts. + body). 5-step retry, auto-pause.
Threshold-Hold
Small jobs land in hold for your review. Big jobs auto-promote to the queue.

60-second quickstart

Generate a sandbox key in Client → Developer, paste it below, and you'll get a fully-mailed PDF back as the response. No real charges, no real postage.

curl -X POST https://allamericannotice.com/api/v1/notices \
  -H "Authorization: Bearer aan_test_REPLACE_ME" \
  -H "Content-Type: application/json" \
  -d '{
    "notice_type": "notice_to_owner",
    "state": "FL",
    "job_name": "Sunrise Tower",
    "job_number": "ST-001",
    "project_address": "1 Ocean Dr",
    "project_city": "Miami",
    "project_zip": "33101",
    "first_day_on_job": "2026-02-15",
    "amount_due": 24500,
    "customer": {
      "company_name": "Acme General Contractors",
      "address": "100 Main St",
      "city": "Miami",
      "state": "FL",
      "zip_code": "33101"
    },
    "external_reference": "PROCORE-OPP-44219"
  }'

Responses include a work_order_number, status (hold if amount_due is below your auto-request threshold; otherwise request), and a downloadable affidavit PDF URL once mailed.

Authentication

Every request to /api/v1/* needs a Bearer token:

Authorization: Bearer aan_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • aan_test_* — sandbox keys; real PDFs, mock tracking, no Lob, no Stripe.
  • aan_live_* — production keys; real mailings + real charges.
  • Scopes: notices:read, notices:write, account:read, account:write.
  • Rotate or revoke at any time from your Developer dashboard. Rotation is immediate — old key stops working on the next request.

Endpoints

All endpoints return JSON. Open the full reference for request/response schemas and a Try-it-out console.

POST/api/v1/notices
GET/api/v1/notices
GET/api/v1/notices/{id}
GET/api/v1/notices/{id}/tracking
GET/api/v1/notices/{id}/affidavit.pdf
POST/api/v1/notices/{id}/release-hold
GET/api/v1/account/settings
PATCH/api/v1/account/settings
GET/api/v1/activity

Webhooks

Register HTTPS endpoints from your dashboard to receive real-time lifecycle events. Every payload is HMAC-SHA256 signed and includes a delivery ID for idempotency.

Event catalog
Subscribe by exact name or with the wildcard *.
notice.createdA new notice was pushed via /api/v1/notices.
notice.heldNotice landed in hold (below your auto-request threshold).
notice.releasedA held notice was released to the full-service queue.
notice.mailedNotice was handed to USPS (real or sandbox-simulated).
notice.deliveredUSPS confirmed final delivery.
notice.returnedReturned-mail event was logged.
invoice.paidStripe checkout completed for an invoice.
webhook.pingSynthetic test event you can fire from the dashboard.
Signature header
Verify before doing anything else with the payload.
X-AAN-Signature: t=1707955200,v1=53b8a8...e9
X-AAN-Event: notice.created
X-AAN-Event-Id: evt_5d0a...
X-AAN-Delivery-Id: 0b3f...
X-AAN-Timestamp: 1707955200

v1 = HMAC-SHA256(secret, f"{ts}." + raw_body) — hex digest. Reject requests where now - t > 300s to mitigate replay attacks.

Retry policy: 1m → 5m → 30m → 2h → 24h (up to 6 attempts). Endpoint auto-pauses after 10 consecutive failures — re-enable from your dashboard.

Verify the signature

import hmac, hashlib

def verify(secret: str, header_sig: str, raw_body: bytes) -> bool:
    # header_sig = "t=1700000000,v1=abc123..."
    parts = dict(p.split("=", 1) for p in header_sig.split(","))
    ts, v1 = parts["t"], parts["v1"]
    expected = hmac.new(
        secret.encode(),
        f"{ts}.".encode() + raw_body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, v1)

# Flask example
@app.post("/webhooks/aan")
def aan_webhook():
    if not verify(WHSEC, request.headers["X-AAN-Signature"], request.get_data()):
        return "bad sig", 401
    event = request.get_json()
    # event = {"id": "evt_...", "type": "notice.created", "data": {...}}
    return "", 204
Sandbox mode

Use aan_test_* keys to integrate without consequences:

  • Generates a real PDF affidavit — you can preview the output.
  • No Stripe charges, no Zoho invoices, no Lob postage.
  • Mocked USPS / Lob tracking timeline progresses in seconds.
  • All sandbox webhooks include "mode": "test".
Threshold-Hold

Pushes from your CRM are filtered by a per-account dollar threshold:

  • If amount_due ≥ threshold → status request (auto-promoted to the full-service queue).
  • If below threshold → status hold (sits until you call /release-hold or release from the dashboard).
  • Set threshold to 0 to bypass — every order goes to the queue.

Integrations

Connect AAN to your existing stack without writing custom glue code.

Zapier · 6,000+ apps
Wire QuickBooks, Buildertrend, HubSpot, Slack, and more to AAN in minutes.
Procore · Active
OAuth 2.0 + auto-order creation from new Procore projects. Sandbox live.
QuickBooks Online · Beta
2-way sync — mailed notices auto-create QBO invoices for your customers.

Ready to push your first notice?

Sign up, mint an aan_test_* key, and send a notice in under a minute. We're integrating with Procore, JobNimbus, and QuickBooks Online — talk to us about your stack.