Skip to content

CONNECT AN API

Add your own API

Some of the APIs your agent needs are yours alone: an internal service, something behind your firewall, a system only your company runs. You add those to the catalog yourself.

A row you add is private to your organization. Nobody outside it can see it, list it, or read it, until you choose otherwise.


Whose rows they are

Your internal systems are not ours to describe, so the catalog is a registry you can write to.

Names carry their owner

The same way a container image does. nginx is the official one; acme/nginx is Acme's, and both can exist because they were never the same name.

Name Whose it is
slack ours, shipped with EKKA, everyone has it
acme/workday Acme's own, private to Acme
acme/notion Acme's own, published so everyone can use it

Your rows are named <your-org>/<name>, and they keep that name forever, including after publishing. Anyone using one always knows whose it is.

This is also how you override something. If your Slack sits behind a corporate proxy, add acme/slack pointing at the proxy. Nothing is shadowed and nothing has to be renamed, because slack and acme/slack are different names.

Write the file

A catalog row is JSON. The quickest start is an existing row:

ekka api describe slack
ekka api spec slack

A minimal one, with a single read:

{
  "name": "acme/inventory",
  "version": 1,
  "title": "Acme inventory service",
  "base_url": "https://inventory.internal.acme.com",
  "auth": { "kind": "bearer" },
  "credential_format": "A service token from the inventory team.",
  "operations": [
    {
      "call": "listItems",
      "title": "List items",
      "verb": "read",
      "method": "GET",
      "path": "/v1/items",
      "inputs": {}
    }
  ]
}

Three things are worth knowing before you write more than that.

A read must be GET. A read-scoped permission can then never produce a call that changes something. That property is what makes read and write mean anything, so it is enforced rather than encouraged.

Never put a credential in the file. auth says which kind of credential the API takes, never the credential itself. That is refused, and it is refused because a catalog row is readable by everyone who can see it.

A row is never edited. Publish version 2 instead. A plan naming version 1 keeps running exactly what it ran yesterday, which is the point.

Check it before you add it

ekka api catalog validate acme-inventory.json

It names the row it would create, lists the operations in it, and says that nothing was written.

This is not a spell-check. EKKA runs the real insert against the real rules and then throws it away, so the answer is exactly what adding it would say. If something is wrong you get the field:

✗ govern refused this row (invalid_body)
  • operations[0].method: a read or list operation must use GET

Add it

ekka api catalog add acme-inventory.json
✓ Added acme/inventory@1
  1 operation, private to this organization.

No deploy, no upgrade, no waiting. It is in the catalog now:

ekka api list
ekka api describe acme/inventory
ekka api spec acme/inventory        # the plan step to copy

From here it behaves exactly like any other API. Connect it with ekka api connect acme/inventory, and the credential goes into your Enclave's vault on your own machine, as always.

Getting a row wrong, and fixing it

A row is never edited, so a wrong base_url or a mistyped path is fixed by adding the next version. That leaves version 1 in the menu though, still offered beside the good one. Archiving is how you take it out.

ekka api catalog archive acme/inventory@1
✓ Archived acme/inventory@1

  It is out of `ekka api list`, and the name on its own no longer resolves to
  it. Nothing breaks: a connection pins a version and a plan already holds the
  whole call, so anything using it keeps working.

Nothing connected to it breaks. A connection points at a specific version, and a plan already carries the whole request it will send, so neither one looks this row up again. You can still read an archived row by naming its version, which is how you see what an old connection is pinned to:

ekka api describe acme/inventory --version 1

To undo it:

ekka api catalog unarchive acme/inventory@1

You can archive rows your own organization added. The ones that ship with EKKA belong to whoever runs your installation.

Sharing it, if you want to

You may not want to. Most internal APIs should stay private, and that is the default. You never have to do anything to keep a row to yourself.

If a row would be useful to other EKKA customers, offer it:

ekka api catalog publish acme/notion@1
✓ Offered acme/notion@1
  It stays private to this organization until EKKA approves it.

Nothing changes until we read it and approve. We do that so a row nobody has checked does not reach other customers.

When it is approved it becomes visible to everyone, and it stays acme/notion. Publishing makes a row visible; it never makes it ours.

Telling yours from ours

ekka api list
NAME              TITLE                    WHOSE            CREDENTIAL
slack             Slack Web API            this EKKA        bearer
acme/inventory    Acme inventory service   yours (private)  bearer
globex/notion     Notion                   published        bearer
WHOSE What it means
this EKKA shipped with your installation
yours your organization's row, which you can publish or archive
published another organization's row, offered and approved

The column answers the question you actually have, which is whether you can change it.

Running EKKA yourself

On a self-hosted installation your own platform team holds the admin role, so the rows marked this EKKA are yours to manage too, added with the same commands. Nothing about this needs us.