Developers
Connect your system to uBumi
Your client's AI team can read live data from the application you built for them. It takes one API key, a health endpoint and one data endpoint — about fifteen minutes of work.
The business owner gives uBumi three things: your API address, an API key, and a list of endpoints. uBumi then calls your system live, with that key, at the moment it needs an answer.
Nothing is exported into uBumi and nothing is uploaded by hand. An AI employee asks your system “who has a payment due this week?”, reads the reply, and works from it. It can only reach the endpoints the owner listed — it cannot compose a URL of its own, so an admin route you did not hand over stays out of reach.
1. Create an API key
There is nothing to request from uBumi — you generate this yourself. Any long random string, kept in your environment and never in source control.
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# .env
UBUMI_KEY=3f9a…2. Add a health endpoint
uBumi calls this once, when connecting, and refuses to store a key it could not verify. It only has to return JSON and a 200.
app.get('/api/ubumi/health', (req, res) => {
if (req.get('authorization') !== `Bearer ${process.env.UBUMI_KEY}`)
return res.status(401).json({ error: 'bad key' });
res.json({ ok: true });
});3. Add the data endpoints
One per question the business wants its AI team to be able to ask. Return plain JSON, and include what a person would need to act: a name, a way to reach them, the amount, the date. Keep each response under 512 KB.
app.get('/api/ubumi/clients', async (req, res) => {
if (req.get('authorization') !== `Bearer ${process.env.UBUMI_KEY}`)
return res.status(401).json({ error: 'bad key' });
const rows = await db.query(
`SELECT id, name, email, phone, amount_due, due_date
FROM loans WHERE due_date < now() + interval '7 days' LIMIT 200`
);
res.json({ clients: rows });
});4. Mount them before the catch-all
This is the one that catches nearly everyone. If your single-page app's catch-all is registered first, Express answers /api/… with index.html and your endpoint is never reached. The symptom is a 200 that returns a web page.
app.use('/api/ubumi', ubumiRoutes); // ← API first
app.get('*', (req, res) => res.sendFile(indexHtml)); // ← catch-all last5. Test it before handing it over
If these two do not behave exactly like this, uBumi will not connect.
# must return JSON, not HTML
curl -s -H "Authorization: Bearer $UBUMI_KEY" \
https://yourdomain.com/api/ubumi/health
# must return 401
curl -s -o /dev/null -w "%{http_code}\n" \
https://yourdomain.com/api/ubumi/healthRequirements
| HTTPS | Required. A key must never travel in the clear, so http:// is refused outright. |
| JSON | Every response, including the health check. HTML is treated as a misconfigured route. |
| GET only | uBumi never sends POST, PUT, PATCH or DELETE. It cannot change anything in your system. |
| No redirects | A 3xx is refused rather than followed. Give the final address. |
| Public address | Must resolve to a public IP. Private, loopback and link-local ranges are refused. |
| Timeout | 15 seconds. |
| Size | 512 KB per response. |
| Auth | Authorization: Bearer, a header of your choosing such as x-api-key, or a query parameter. |
Why a connection gets refused
These are the messages the business owner sees, so a complaint maps straight to a cause.
| returned a page rather than JSON | The single-page app's catch-all is answering. See step 4. |
| rejected the token | Your health endpoint replied 401 or 403. |
| must start with https:// | An http:// address was given. |
| redirects elsewhere | A 3xx was returned. Supply the address it redirects to. |
| points at a private network | The hostname resolves to an internal address. |
| credential in the address | A key was embedded in the URL instead of the token field. |
If you already publish an OpenAPI document
The owner can paste its address and the endpoint list fills itself in. uBumi imports GET operations only, and skips any path containing {braces}, because it has no way to guess the value. The summary field matters more than you would expect: it is how an AI employee decides whether an endpoint is worth reading.
What to send back
| API address | https://yourdomain.com/api/ubumi |
| Health path | /health |
| Endpoints | clients → /clients → “Members with a payment due this week” |
Send the key by something other than email — a password manager, or let the business owner paste it into their own workspace so it passes through fewer hands. Write the endpoint description in plain words: it is the sentence an AI employee reads when deciding what to call, and a path on its own tells it nothing.
uBumi reads; it does not write. Every request is logged against the workspace, the key is encrypted before it is stored and never shown again, and the owner can disconnect at any time from the Integrations page.
Early access
See Amina and Pendo on your own inbox.
A configured pilot, two weeks of shadow mode, nothing sent without your approval.
