Partner API Documentation

Integrate expert-reviewed 409A valuations into your product: create a valuation, upload documents, track review status, and download the final report PDF, with signed webhooks at every step. The Partner API is rolling out to invited partners. Keys are issued by the partnerships team to approved partners.

Overview

The 409.AI Partner API lets your product offer expert-reviewed 409A valuations as a native feature. Your integration creates a valuation from a submission package, uploads supporting documents, submits it for review, tracks status, and downloads the final report PDF. Signed webhooks keep your system in sync the whole way.

The API is reviewed-final only: it never returns an unreviewed number. Drafts are produced internally in about 24 hours, finals are delivered within 7 business days (express delivery in 1 or 3 business days is available for a $500 fee), and every report is reviewed by CPA, CFA®, and FRM® credentialed professionals before it can be downloaded.

  • Base URL: https://platform.409.ai/partner/v1, JSON in and out
  • Auth: Authorization: Bearer sk409_... on every request, server-side only
  • Interactive reference: full schemas and a try-it console at platform.409.ai/partner/docs
  • Data isolation: customer data is used only to prepare that customer's report

The Partner API is rolling out to invited partners. Keys are issued by the partnerships team to approved partners and the integration is scoped together on a call: request API access to get started.

How it works

A valuation moves through a small set of statuses from intake to delivered report. Create it, attach documents, submit it, and our credentialed team takes it from there.

StatusWhat it meansWhat your system does
receivedThe submission landed and is queued for analysisNothing; wait for the next transition
needs_informationThe reviewer needs more from the customerUpdate the package or upload the missing documents, then submit again
in_reviewCredentialed professionals are reviewing the reportNothing; you are notified when review completes
final_readyThe reviewed final report is approvedDownload report.pdf and deliver it to your customer
closedThe valuation was closed (terminal)Treat it as ended; create a new valuation if needed

Each transition fires a valuation.status_changed webhook, and report.ready fires when the final PDF becomes available, so most integrations never need to poll.

Authentication

Every request carries your secret key in the Authorization header. Keys are issued by the partnerships team to approved partners, shown once at issuance, and revocable at any time. Treat them like passwords: store them in a secret manager and call the API from your servers only, never from a browser or mobile app.

curl https://platform.409.ai/partner/v1/me \
  -H "Authorization: Bearer sk409_..."

GET /v1/me returns the partner identity behind the key, which makes it a handy connectivity check. If a key is ever exposed, contact the partnerships team and it will be revoked and reissued.

Quickstart: intake to report

Five calls take a valuation from intake to a delivered report. The full submission package schema lives in the interactive reference.

curl -X POST https://platform.409.ai/partner/v1/valuations \
  -H "Authorization: Bearer sk409_..." \
  -H "Idempotency-Key: 6b9f6f0e-8d1c-4b3a-9d64-2f9a1c7e5b21" \
  -H "Content-Type: application/json" \
  -d @submission.json

Responds 201 with {"id": "18024", "status": "received"}. Set type to "409a" and pass your own customer identifier as external_id; it is scoped to your partnership.

curl -X POST https://platform.409.ai/partner/v1/valuations/18024/documents \
  -H "Authorization: Bearer sk409_..." \
  -F "file=@captable.xlsx" \
  -F "category=captable_documents"

Responds 201 per file. Categories: captable_documents, monthly_income_statements, annual_income_statements, balance_sheets, projections_files, and uploads for anything else.

curl -X POST https://platform.409.ai/partner/v1/valuations/18024/submit \
  -H "Authorization: Bearer sk409_..."

Responds 200 when the package is complete. If anything is missing it responds 422 with a missing[] array naming exactly what to add.

curl https://platform.409.ai/partner/v1/valuations/18024 \
  -H "Authorization: Bearer sk409_..."

Responds 200 with the current status, for example {"id": "18024", "status": "in_review"}. Prefer webhooks for updates; poll only as a fallback.

curl https://platform.409.ai/partner/v1/valuations/18024/report.pdf \
  -H "Authorization: Bearer sk409_..." \
  -o report.pdf

Responds 200 with the PDF once the valuation is final_ready. Before expert approval it responds 409 with code report_not_ready: only reviewed finals ever leave the API.

Endpoints

MethodPathPurpose
POST/v1/valuationsCreate a valuation from a submission package (Idempotency-Key supported, partner-scoped external_id)
PUT/v1/valuations/{id}Replace the submission package any time before the report is final
POST/v1/valuations/{id}/documentsUpload a supporting file (multipart: file + category)
POST/v1/valuations/{id}/submitSubmit for review; 422 with missing[] when incomplete
GET/v1/valuations/{id}Retrieve the valuation and its current status
GET/v1/valuations/{id}/report.pdfDownload the reviewed final report (409 report_not_ready before approval)
PUT/v1/webhookCreate or rotate your webhook endpoint; returns the signing secret
GET/v1/webhookInspect the registered webhook endpoint
DELETE/v1/webhookRemove the webhook endpoint
POST/v1/webhook/testSend a signed test event to your endpoint
GET/v1/meIdentify the partner behind the API key

Request and response schemas for every endpoint, with a try-it console, are in the interactive API reference.

v1 accepts one report type today: "409a". The spec already declares the full 13-type catalogue (409A, SMB, ASC 718, IFRS 2, ASC 820, QSBS, gift and estate tax, ESOP, EMI, CSOP, PPA, impairment testing, and IP) in its type enum, so additional types can arrive without a breaking change. Enum values are the spec codes, so SMB is passed as fmv.

Webhooks

Each partner registers one webhook endpoint. PUT /v1/webhook creates or rotates it and returns the whsec_... signing secret exactly once per rotation, so store it immediately.

curl -X PUT https://platform.409.ai/partner/v1/webhook \
  -H "Authorization: Bearer sk409_..." \
  -H "Content-Type: application/json" \
  -d '{"url": "https://api.example.com/webhooks/409ai"}'
  • Events: valuation.status_changed on every transition, and report.ready when the final PDF is available
  • Envelope: {id, type, created_at, data}, delivered as JSON with the event id repeated in the X-409AI-Delivery header
  • Signature: X-409AI-Signature: t=<unix>,v1=<hex(HMAC_SHA256(secret, "{t}.{body}"))>
  • Retries: failed deliveries retry at 1m, 5m, 30m, 2h, and 12h, then the delivery is marked failed

Verify the signature before trusting any delivery, and reject stale timestamps to block replays:

import hashlib, hmac, time

def verify(signature_header, body, secret, tolerance=300):
    parts = dict(item.split("=", 1) for item in signature_header.split(","))
    timestamp, received = int(parts["t"]), parts["v1"]
    if abs(time.time() - timestamp) > tolerance:
        return False
    expected = hmac.new(secret.encode(), f"{timestamp}.".encode() + body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, received)

POST /v1/webhook/test sends a signed test event on demand, which makes handler development a one-command loop.

Errors

Every error uses one envelope, and every response carries an x-request-id header (mirrored as request_id in error bodies). Log it and include it when you contact support.

{
  "error": {
    "code": "report_not_ready",
    "message": "The report has not been approved for release yet."
  },
  "request_id": "req_9f2d41c8a7"
}
CodeHTTPMeaning
unauthorized401Missing, malformed, or revoked API key
not_found404The valuation does not exist or belongs to another partner
invalid_request422The request body is malformed or fails validation
validation_failed422The submission is incomplete; missing[] lists what to add
idempotency_conflict409The Idempotency-Key was reused with a different body
external_id_conflict409The external_id is already attached to another valuation
locked409The valuation can no longer be modified
report_not_ready409The final report has not been approved yet
payload_too_large413The uploaded file exceeds the size limit
rate_limited429Too many requests; retry after the Retry-After header

Limits and versioning

  • Rate limits: 120 requests per minute per key, and 20 per minute for document uploads. A 429 includes Retry-After; back off for that many seconds
  • Idempotency: send a unique Idempotency-Key (a UUID works well) on POST /v1/valuations so network retries never create duplicates; reusing a key with a different body returns 409 idempotency_conflict
  • External ids: external_id is scoped to your partnership and enforced as unique, a second guard against duplicate intakes

The API is versioned in the path: everything documented here lives under /v1. Additive changes (new optional fields, new enum values, new endpoints, new webhook event types) may ship within v1, so build your parsers to ignore fields they do not recognize. Breaking changes will only ever arrive under a new version path.

Frequently asked questions

How do I get an API key?

The Partner API is invite-only. Request access through the partner form on the partners page or write to partners@409.ai, and the partnerships team will scope the integration together with you on a call. Keys are issued to approved partners, shown once at issuance, and can be revoked or rotated at any time.

Is there a sandbox?

Not a public one yet. Onboarding is hands-on: the partnerships team scopes a safe path to production with you on a call, and POST /v1/webhook/test sends signed test events on demand so you can build and verify your webhook handler end to end before real traffic arrives.

Which report types can I create?

v1 accepts the "409a" report type today. The API spec already declares the full 13-type catalogue (409A, SMB, ASC 718, IFRS 2, ASC 820, QSBS, gift and estate tax, ESOP, EMI, CSOP, PPA, impairment testing, and IP) in its type enum, so one integration will cover additional types as they roll out.

Is the report PDF white-labeled?

Yes. Reports delivered through the API carry the partner's branding per your white-label agreement, which is scoped during onboarding. Your customers see your brand on the deliverable.

How fast are reports delivered?

Drafts are produced internally in about 24 hours and final reports are delivered within 7 business days, with express delivery in 1 or 3 business days available for a $500 fee. The API only ever returns the reviewed final: every report is reviewed by CPA, CFA®, and FRM® credentialed professionals before report.pdf becomes available.

How is my customers' data used?

Customer data is used only to prepare that customer's report. We never market to your customers or resell their data.

Request API access or open the interactive API reference.