uBumi

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 last

5. 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/health

Requirements

HTTPSRequired. A key must never travel in the clear, so http:// is refused outright.
JSONEvery response, including the health check. HTML is treated as a misconfigured route.
GET onlyuBumi never sends POST, PUT, PATCH or DELETE. It cannot change anything in your system.
No redirectsA 3xx is refused rather than followed. Give the final address.
Public addressMust resolve to a public IP. Private, loopback and link-local ranges are refused.
Timeout15 seconds.
Size512 KB per response.
AuthAuthorization: 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 JSONThe single-page app's catch-all is answering. See step 4.
rejected the tokenYour health endpoint replied 401 or 403.
must start with https://An http:// address was given.
redirects elsewhereA 3xx was returned. Supply the address it redirects to.
points at a private networkThe hostname resolves to an internal address.
credential in the addressA 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 addresshttps://yourdomain.com/api/ubumi
Health path/health
Endpointsclients → /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.

Request early access