Try it

Menu

Your AI assistant can set up your website or app with you, and your tools can read /llms.txt.

Developers

Connect your product: invite people, report outcomes, and hear by webhook which are verified, then paid after the deadline.

Your API key: an owner or a developer creates it in your dashboard, under Integrations. Quickstart

  1. You invite, or share the join link; people join themselvesPOST /api/v1/invitationsinvitation.joined
  2. Your app reports an outcomePOST /api/v1/outcomes
  3. Your organization’s verifier decides, or auto-verify on a trial campaignoutcome.verifiedoutcome.rejected
  4. Your organization pays the person after the deadlineoutcome.paid
  5. The person keeps a certificate, checkable once they publish itCertificates

Report an outcome

POSThttps://campaign.udao.org/api/v1/outcomes

Report one when a person finishes. It is kept against their place with a hash of what you sent, and the same external_id twice answers the first reply again. An outcome for someone who has not joined yet is kept as a record. Reporting moves no money: your organization pays each reward from its own account.

curl https://campaign.udao.org/api/v1/outcomes \
  -H "Authorization: Bearer camp_sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
      "campaign_id": "8f2c6a1e-4b7d-4e39-a5c0-3d9e1f6b2a74",
      "email": "ada@example.com",
      "reference": "course-solidity-101",
      "occurred_at": "2026-09-11T14:03:22Z",
      "external_id": "your-own-id-8f3a",
      "kind": "completed"
    }'
202 Accepted
{
  "external_id": "your-own-id-8f3a",
  "campaign_id": "8f2c6a1e-4b7d-4e39-a5c0-3d9e1f6b2a74",
  "status": "pending",
  "reason": "awaiting_review",
  "received_at": "2026-09-11T14:03:25Z",
  "outcome_url": "https://campaign.udao.org/api/v1/outcomes/your-own-id-8f3a?campaign_id=8f2c6a1e-4b7d-4e39-a5c0-3d9e1f6b2a74"
}

Authorization

Every call carries one header, your API key, and nothing else. An owner or a developer creates it, and needs a sign-in from the last 10 minutes. It is shown once; keep it on your server, never in a browser. Your organization keeps at most 10 live.

Authorization: Bearer camp_sk_live_...

An API key for trial campaigns only begins camp_sk_trial_ and writes to trial campaigns alone. Trial campaigns are the test mode: the loop runs whole and every figure comes back with simulated true.

The base address

https://campaign.udao.org

Public reads

  • GET/api/public/campaigns/{id}No API key. It answers a campaign’s public facts: its title, reward, places, dates and who funds it, up to 120 requests a minute from one address.
  • The certificate readsNo API key either.Certificates

These get the same 404 campaign_not_found:

  • a campaign before it goes live or after it is closed or canceled
  • an id nobody holds
  • while Udao has not approved the organization, any reader but its signed-in members, the people it invited and the people holding a place

Versions and changes

This is version 1, in the path. We only add to it: new endpoints, new optional fields, new fields in answers and webhooks, new reasons and codes. Ignore what you do not know. Anything that would break a client comes as version 2, beside version 1, announced here at least 30 days ahead.

  • 2026-10-10Revoking a verified or paid outcome, or inviting, on a real campaign answers 403 power_not_granted unless an owner gave the API key that. Reading a real campaign’s outcome or invitation with an API key for trial campaigns only answers 409 trial_only_credential.
  • 2026-10-05Invitations: POST /api/v1/invitations puts one person on a campaign’s list, its read answers invited, joined or removed, and invitation.joined says when they join.
  • 2026-10-04The API published as one OpenAPI 3.1 document and a Postman collection. The read no longer lists proof, which it never sent.
Read the quickstart