Canapi Documentation
Getting Started
Canapi lets you attach a charitable cause to any action in your app or website - a purchase, a signup, a completed task. When your users do something, Canapi logs a contribution toward a cause on your behalf. Your users see the impact. The contribution is tracked, billed to you monthly, and fulfilled by the cause's provider.
Getting up and running takes about 15 minutes and requires no changes to your existing infrastructure beyond a single API call.
Before you begin, you will need:
- A Canapi account - sign in through the login page or request a Beta account via email
- An active Canapi instance configured with a cause and domain whitelist
- An API key generated for that instance
Getting Your API Key
Each Canapi instance has its own API key. Keys are generated from the instance page in your portal.
- Log in and navigate to Instances
- Select the instance you want to integrate
- Under API Key, click Regenerate Key and confirm
- Copy the key immediately - it is shown once and never stored
Keep your API key secret. It should never be committed to source control or exposed in client-side code. Store it as an environment variable on your server, or in your platform's secrets manager.
Your key will look like this:
xxx_aLotOfNumb3rsAndCharact3rsThatL00ksScaryButIsJustSecur3
Making a Contribution
When something meaningful happens in your app - a completed order, a finished workout, a booked appointment - send a single POST request to the Canapi contribute endpoint. Canapi handles the rest.
Endpoint
POST https://us-central1-terrabyte-canapi.cloudfunctions.net/contribute
Authentication
Pass your API key as a Bearer token in the Authorization header:
Authorization: Bearer xxx_your_api_key_here
Domain whitelisting
Canapi validates requests against the domain whitelist configured on your instance. The domain is read automatically from the Origin or Referer header of the incoming request - browsers set these automatically. For server-side requests, set the Origin header manually to the domain registered on your instance's domain whitelist.
Example — JavaScript (browser or Node.js)
const response = await fetch(
'https://us-central1-terrabyte-canapi.cloudfunctions.net/contribute',
{
method: 'POST',
headers: {
'Authorization': 'Bearer xxx_your_api_key_here',
'Content-Type': 'application/json',
'Origin': 'https://yourwebsite.com' // required for server-side requests
}
}
);
const data = await response.json();
if (data.status === 'success') {
console.log(`Contribution logged - action ID: ${data.actionId}`);
console.log(`Cause: ${data.causeId}`);
// e.g. "Your order helped plant a tree!"
}
Example — cURL
curl -X POST https://us-central1-terrabyte-canapi.cloudfunctions.net/contribute \
-H "Authorization: Bearer xxx_your_api_key_here" \
-H "Origin: https://yourwebsite.com"
Where to place the call
Call the endpoint at the moment the meaningful action is confirmed - after a payment is captured, after a form is successfully submitted, after an order is fulfilled. Avoid calling it speculatively (e.g. when a user adds something to a cart) since contributions are billed and logged as completed actions.
Response Reference
A successful contribution returns HTTP 200 with the following JSON body:
{
"status": "success",
"actionId": "abc123xyz",
"causeId": "plant-a-tree"
}
| Field | Type | Description |
|---|---|---|
status |
string | Always "success" on a 200 response |
actionId |
string | Unique ID for this contribution. Keep this if you want to reference the action later or display it to your user |
causeId |
string | The cause tied to your instance - use this to show your users what their action supported (e.g. "Your order planted a tree") |
Error Reference
All error responses return JSON with a single error field describing the problem.
| Status | Error | What it means |
|---|---|---|
401 |
Missing API key | No Authorization header was sent |
401 |
Invalid API key | The key doesn't match any active instance - check for typos or regenerate your key |
403 |
Instance is not active | The instance tied to this key is inactive or archived |
403 |
Domain not permitted | The request's origin doesn't match the domain whitelist on your instance |
429 |
Rate limit exceeded | Your instance has hit its configured hourly contribution cap - the request was not logged as a billable action |
500 |
Internal server error | Something went wrong on our end - try again, and contact support if the problem persists |