> ## Documentation Index
> Fetch the complete documentation index at: https://evsim.synergyboat.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Connect a local endpoint

> Test an OCPI implementation that runs on localhost or inside a VPC by putting a tunnel in front of it, and what that costs you while the tunnel is up.

Your OCPI implementation runs on `http://localhost:8000`, or on a machine inside a VPC
that only your own network can reach. The tester is hosted, and it calls your endpoint
server to server. It cannot reach a laptop.

This is the normal state of a half-built integration, not a mistake you made. The fix that
works today is a tunnel: a small program you run next to your service that gives it a
temporary public HTTPS URL. You then use that URL as the base URL of a connection, exactly
as you would a partner's.

## What we do not ask you for

* No inbound firewall rule.
* No public hostname of your own.
* No TLS certificate on your side. The tunnel terminates HTTPS for you.

Your service keeps listening on plain HTTP on localhost. Nothing about it changes.

## Start a tunnel

Both of these give you a random HTTPS URL and print it in the terminal. Pick one. Replace
`8000` with the port your OCPI service listens on.

### cloudflared

```bash theme={null}
brew install cloudflared          # or see the Cloudflare install docs for your OS
cloudflared tunnel --url http://localhost:8000
```

It prints a line with a `https://<random-words>.trycloudflare.com` URL. That is your
public base URL. No account is needed for this kind of quick tunnel.

### ngrok

```bash theme={null}
brew install ngrok                # or see the ngrok install docs for your OS
ngrok config add-authtoken <your ngrok authtoken>
ngrok http 8000
```

It prints a `Forwarding` line with a `https://<random>.ngrok-free.app` URL. That is your
public base URL. ngrok needs a free account for the authtoken, and it needs it only once
per machine.

Leave the tunnel running for as long as you are testing. Both tools issue a **new random
URL every time you restart them**, so if you stop and start the tunnel, the connection you
created points at a URL that no longer exists.

## Check it from outside your machine

Before you create a connection, prove the tunnel reaches your service:

```bash theme={null}
curl -fsS "https://<your-tunnel-host>/ocpi/versions" \
  -H "Authorization: Token <your token A>"
```

If that answers, we can reach you too. If it does not, fix it here rather than in a run
report.

## The part that costs people an afternoon

The tunnel host has to be the base URL you register **and** the host your own responses
advertise.

OCPI is a discovery protocol. Our client reads your `/versions` response, follows the
`url` it finds there to your version details, and follows those `endpoints` URLs to every
module. If your service builds those URLs from its local configuration, it will hand back
`http://localhost:8000/ocpi/2.2.1/cdrs`, and our client will follow that straight back to
a loopback address on our server, which is not your machine.

The symptom is confusing: registration looks fine, then every module fails as though your
endpoints do not exist.

So set whatever your service uses as its public base URL (an environment variable in most
implementations) to the tunnel host before you start it, and confirm it with the `curl`
above. Every URL in the response should name the tunnel host.

## Point a connection at it

From here nothing is special. Create the connection with the tunnel URL as
`partnerBaseUrl` and register it, the same as any partner:

```bash theme={null}
curl -fsS -X POST "https://evsim.synergyboat.com/api/v1/connections" \
  -H "Authorization: Bearer $EVRT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "partnerBaseUrl": "https://<your-tunnel-host>/ocpi",
    "ourRole": "EMSP",
    "theirRole": "CPO",
    "tokenA": "YOUR-TOKEN-A",
    "ocpiVersion": "2.2.1"
  }'
```

[Connect a partner endpoint](/docs/guide/connect-a-partner) covers the fields, the registration
handshake, and the version choice. Everything on that page applies here.

## What this costs you

**While the tunnel is up, your service is on the public internet, and anyone who has the
URL can reach it.** There is no way around that: a tunnel works by making your service
reachable, and reachable means reachable by whoever holds the address.

The mitigations that actually exist:

* **The URL is random and temporary.** Nobody can guess
  `https://<random-words>.trycloudflare.com`, and it stops working when you stop the
  tunnel. This is real protection against strangers, and no protection at all against
  anyone you sent the URL to.
* **Our requests carry the token you configured**, and nothing else about the tunnel
  changes your authentication. If your service rejects requests without a valid OCPI
  token, it still rejects them through the tunnel. This is your actual access control. If
  your service does not check the token yet, the tunnel is the wrong time to find that out.
* **Stop the tunnel when the run finishes.** The exposure lasts exactly as long as the
  process does. Stopping it costs you nothing except a new URL next time.
* **Use throwaway data.** A development database with invented CDRs and test tokens, never
  a copy of production.

<Warning>
  The login features these tools offer for protecting a URL (ngrok's OAuth, Cloudflare
  Access) put a browser sign-in in front of your service. Our requests are not a browser
  and cannot sign in, so turning those on will block us along with everyone else. Treat
  your own OCPI token check as the control that matters, and keep the tunnel window short.
</Warning>

If none of that is acceptable to you, say so rather than working around it. The connector
below is being built for exactly that answer.

## Speed

A conformance run is sequential and small. Each request crosses the internet twice more
than it otherwise would, which adds tens of milliseconds per request and changes no
verdict. A tunnel is fine for conformance.

A load run is different. It measures the tunnel as much as it measures you, so the numbers
it produces are not about your service. Do not size anything from a load run over a tunnel.

## A connector is coming

We are building a connector: a small binary you run next to your service that opens an
**outbound** connection to us and forwards our requests to a local address you name. It
needs no inbound firewall rule, no public hostname and no TLS certificate, and it never
puts your service on the public internet. It removes the trade-off on this page.

It is not available yet, and we are not going to give you a date for it. Use a tunnel
today. If a tunnel is not something you can do, [tell us](mailto:ahoy@synergyboat.com) and
we will let you know when the connector is ready.

## Next

1. [Connect a partner endpoint](/docs/guide/connect-a-partner) to create and register the
   connection.
2. [Run a conformance suite](/docs/guide/run-a-suite) against it.
