One gateway, two kinds of caller

ApiArk puts a real gateway in front of an HTTP API and then decides, per caller, what that caller may reach. A person gets a key. An agent gets a token and a list of operations. Both travel the same checks and land in the same log.

We run the gateway, so there is nothing to operate and no configuration to write. Below is what each path gives you, at the level of detail you would want before pointing traffic at somebody else’s infrastructure.

Giving an agent access

An agent that can reach your API through ApiArk holds a token that opens the operations you ticked and nothing else. This is the newer of the two paths and the one with no equivalent that starts on your laptop.

Every operation becomes a tool
Import an OpenAPI document and ApiArk reads the operations out of it. When the app serves no spec, which is most local Express and Fastify apps, type the method and path by hand. Either way you end up with a list you tick.
The selection is enforced, not suggested
Ticking three read operations creates an agent that reaches exactly those routes. A call to anything else is refused with a 403 before your backend hears about it. The agent is not being asked to behave.
The agent has its own identity
Each agent gets its own identity on the gateway, which means its own key, its own share of the daily count, and its own rows in the request log. You can see what one agent did without untangling it from your own traffic.
One line in the client
You get an MCP URL and a bearer token, and paste them into Claude Code, Claude Desktop, Cursor or Pi as a header. There is no server to host and no SDK to import. claude.ai on the web and ChatGPT need OAuth, which is not built.
Revocation is one action
Deleting the agent withdraws its access in the same operation. There is no interval where a token you meant to kill still opens a route.
Both MCP revisions
The stateless flow from revision 2026-07-28 and the older initialize handshake, chosen per request, so a client on either side of that change works without you picking a side.
agents / new / capabilities3 of 6 selected

Three of six operations ticked. The agent gets listOrders, getOrder and searchOrders. Everything else answers 403.

agents / orders-roactive
name
orders-ro
consumer
fox_orders_ro_a41c9e2b7f03
token
sha256:9c4a…e10f
operations
3 of 6
daily count
412 of 1,000
created
2026-08-25 09:14

Deleting the agent unwhitelists its consumer in the same action.

logs / agent: orders-rolast 4 calls
Four calls an agent made through the gateway. The last one, deleteOrder, was not among the operations granted to it and came back 403.
agenttoolstatus
orders-rolistOrders200
orders-rogetOrder200
orders-rosearchOrders200
orders-rodeleteOrder403

deleteOrder was never ticked, so the gateway refused it. Not the agent’s restraint, the gateway’s.

Exposing an API

The path most people arrive on. It replaces a tunnel plus whatever you were going to bolt onto it once the URL was public.

A public HTTPS URL for a local port
Run one command against the port your API already listens on and you get a stable public address. Webhooks from Stripe or Slack reach your laptop while you are still writing the handler.
Key auth on every route
Keys are issued at signup and managed from the dashboard. A caller without a valid key never reaches your backend, and you did not write a middleware to make that true.
Rate limits counted per key
The count lives at the gateway, so a leaked key or a runaway script is stopped at the edge and costs you no bandwidth and no compute. Over the limit answers 429 with the headers a client needs to back off.
Every request logged
Method, path, status and latency, streamed to the dashboard as calls arrive. Request bodies are not captured, not inspected and not written to disk.
Already deployed APIs too
An API on a server or a cloud host does not need the CLI at all. Create the route from the dashboard, point it at the upstream, and it runs the same checks.
Nothing installed in your backend
No library, no SDK, no framework requirement. ApiArk sits in front of the API and forwards to it, which is why the language on your side never comes up.
routes / foxcreated
public url
https://api.apiark.io/fox
upstream
tunnel → localhost:3000
key auth
on
rate limit
1,000 / day, per key
request log
on, streaming
backend changes
none
logs / project: foxlast 5 requests
Five requests through the gateway. One failed authentication with 401 and one exceeded the daily count with 429, both stopped at the edge.
methodpathstatus
GET/fox/orders200
POST/fox/orders201
GET/fox/customers200
POST/fox/webhooks401
GET/fox/orders429

The 401 and 429 never reached the backend. They cost you no bandwidth and no compute.

Both paths start with the same free account

Free plan: one project, 1,000 requests a day, no card. Open beta.