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

# Connect a partner endpoint

> Create a connection for a real partner OCPI endpoint and run the live credentials registration handshake before you test against it.

A **connection** is a partner OCPI endpoint you test against. Setting one up is two API
calls: create it, then register it. Creation records who you are, who they are, and the
token they gave you. Registration performs the live OCPI credentials handshake, and it is
the step that usually goes wrong.

## What you need from your partner

Two things, and they come from them, not from us:

| You need            | What it is                                           |
| ------------------- | ---------------------------------------------------- |
| Their OCPI base URL | The URL their versions endpoint hangs off.           |
| Token A             | A registration token they issue to you, out of band. |

Token A is not something you generate for this direction. The OCPI specification is
explicit that it is created by the receiving party and passed to you "in a secure way that
is outside the scope of this protocol": an email, a portal, a phone call. If your partner
asks *you* for Token A, they mean to register into you instead, which is the opposite
direction and has [its own page](/guide/let-a-partner-register).

### The address has no shape you can guess

The base URL travels out of band with Token A, and for the same reason: the spec never defines
what it looks like. "The protocol is designed such that the exact URLs of the endpoints can be
defined by each party", and the example URLs in the specification "are descriptive only". So
`/ocpi`, `/api/ocpi` and `/ocpi-2.2.1` are all legal bases, and only your partner knows which one
is theirs. Ask them for it rather than deriving it from anything else they sent you.

The one that catches people is the versions URL itself. What a partner hands over is usually the
full `.../ocpi/versions`, and this field wants the URL that hangs off, one segment shorter. Paste
the whole thing and we ask for `.../ocpi/versions/versions`, which no server advertised. On the
Endpoints page the line under the address names the exact URL the next press will ask for, so a
value one segment out shows itself before it costs you a connection. If you are not sure which of
the two you were given, press **Check this address** and we try the likely candidates and report
what each one answered.

## Create the connection

```bash theme={null}
curl -fsS -X POST "https://chargerdojo.com/api/v1/connections" \
  -H "Authorization: Bearer $DOJO_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "partnerBaseUrl": "https://partner.example.com/ocpi",
    "ourRole": "EMSP",
    "theirRole": "CPO",
    "tokenA": "THEIR-TOKEN-A",
    "ocpiVersion": "2.2.1"
  }'
```

| Field            | Notes                                                                                                                                                                                                                                                                                    |
| ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `partnerBaseUrl` | Their OCPI base URL. It has to be reachable from the internet; if the endpoint you are testing runs on your own machine or inside a VPC, [put a tunnel in front of it first](/guide/connect-a-local-endpoint), or run [the connector](/guide/use-the-connector), which never exposes it. |
| `ourRole`        | `CPO` or `EMSP`. The role **you** are testing as. New to those two? [Glossary](/guide/glossary).                                                                                                                                                                                         |
| `theirRole`      | `CPO` or `EMSP`.                                                                                                                                                                                                                                                                         |
| `tokenA`         | The registration token they issued you.                                                                                                                                                                                                                                                  |
| `ocpiVersion`    | `2.1.1`, `2.2`, `2.2.1` or `2.3.0`. Defaults to `2.2.1`.                                                                                                                                                                                                                                 |

You get back `201` with the connection, its `_id`, and `status: "pending"`. Token fields
are never returned, by us or in any report.

## Pick the version they actually run, not the newest one

The most common setup mistake is selecting 2.2.1 because it sounds current when the
partner is on 2.1.1. Every subsequent failure will then be a version mismatch wearing the
costume of a protocol bug. If you do not know what they run, ask, or read their versions
endpoint. OCPI 2.1.1 is still in wide production use, and there is no shame in it.

<Note>
  The credentials token is transported differently across versions. OCPI 2.1.1 sends it
  raw; from 2.2 onwards it is Base64 encoded. Get the version wrong and authentication
  fails on the very first request, with an error that looks nothing like a version
  problem. The tester handles the encoding for you, but only if you told it the right
  version.
</Note>

## Register: the live credentials handshake

```bash theme={null}
curl -fsS -X POST "https://chargerdojo.com/api/v1/connections/$CONNECTION_ID/register" \
  -H "Authorization: Bearer $DOJO_KEY"
```

This runs the real OCPI credentials handshake against the partner. It is not a simulation
and not an assertion against a stored token: the tester reads their versions endpoint with
Token A, posts its own credentials, and receives the token it will use for every
subsequent call. On success the connection's `status` becomes `registered`. On failure it
records `lastError`, and that error is the thing worth reading.

Registration is where OCPI integrations get stuck, and the failures follow a pattern:
a side keeps presenting the dead registration token after the exchange, a partner never
fetches your endpoints, or the token encoding does not match the version. The
[troubleshooting page](/guide/troubleshooting#registration) walks each one.

## Read your connections

```bash theme={null}
curl -fsS "https://chargerdojo.com/api/v1/connections" \
  -H "Authorization: Bearer $DOJO_KEY"

curl -fsS "https://chargerdojo.com/api/v1/connections/$CONNECTION_ID" \
  -H "Authorization: Bearer $DOJO_KEY"
```

Connections are owner scoped: you see your own, plus the built-in sandbox targets. A
connection id that belongs to someone else answers `404`.

## When their address changes

A partner who moves hosts, or an endpoint of your own behind a tunnel that hands out a new URL,
does not need a new connection. Move the one you have:

```bash theme={null}
curl -fsS -X PUT "https://chargerdojo.com/api/v1/connections/$CONNECTION_ID/address" \
  -H "Authorization: Bearer $DOJO_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "partnerBaseUrl": "https://their-new-host.example/ocpi" }'
```

Their platform has not changed and neither have the tokens, so nothing is re-registered. The
connection keeps its id and its own reports, drops to `pending` while we read their versions
endpoint at the new address, and returns to `registered` when that answers.

This is ours rather than OCPI's. The spec's "changing endpoints" procedure is a credentials `PUT`
that carries **your** versions URL, so it tells a partner that *you* moved. Nothing in OCPI tells a
client that the *server* moved, because a server's versions URL is exchanged out of band in the
first place.

## Next

[Run a conformance suite](/guide/run-a-suite) against the registered connection.
