Create a forge connection, writing its credential through to the secret store (ADR-0060)
const url = 'https://example.com/v1/connections';const options = { method: 'POST', headers: {'Content-Type': 'application/json'}, body: '{"base_url":"example","credential":"example","kind":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://example.com/v1/connections \ --header 'Content-Type: application/json' \ --data '{ "base_url": "example", "credential": "example", "kind": "example" }'This is the manual/UI half of part D and the reason Forgejo can be onboarded at all: GitHub registers itself when the App is installed, but a Forgejo instance has no such event, so without this endpoint its only route into the registry was a hand-written database row.
The credential is write-only in the strong sense — it is written before the connection row exists, never read back by any endpoint, and the response carries only the generated handle. Order matters: writing the secret first means a failure leaves an orphan secret (harmless, overwritten on retry) rather than a connection whose credential never landed (a live row that silently cannot authenticate).
Request Bodyrequired
Section titled “Request Bodyrequired”POST /v1/connections body (ADR-0060 part D, manual path): the forge to
connect and the credential to reach it with.
credential is write-only — it is written through to SecretProvider
under a server-generated handle and never appears in any response. There is
deliberately no “update the credential” field on the read DTO: a secret you
can read back is a secret you have leaked.
object
The instance root Scarab talks to (e.g. https://codeberg.org). A
trailing slash is normalized away.
The forge access token. Write-only (see the struct docs).
forgejo. GitHub is not creatable here — installing the App is its
registration (ADR-0060 part C), so a create form for it could not work.
Examplegenerated
{ "base_url": "example", "credential": "example", "kind": "example"}Responses
Section titled “Responses”POST /v1/connections response: the created connection’s id and the
generated handle its credential now lives under. Not the credential.
object
The server-generated _forge-scoped handle. Echoed so an operator can
correlate the row with its secret; it is a name, not a value.
Examplegenerated
{ "credential_ref": "example", "id": "example"}Unknown kind, non-creatable kind, or a malformed base URL
Requires Administer on the org
No connection registry or secret store wired
A connection to that forge and base URL already exists