Rename or update a connection
PUT/
Renames a connection, or changes its details.
Needs an API token with the Write permission for connections (connection:write).
Parameters
Path
idRequired · UUIDThe connection’s ID.
Body
nameOptional · stringUp to 255 characters, trimmed, not blank. Needed when there is no
config.configOptional · objectLeft out: only a rename, and the details stay. Sent: merged over the saved ones. A field left out or blank keeps its value;
nullremoves it.testOptional · booleantruetests the merged details first and saves only if the service accepts them.
What are the rarely used parameters?
authTypeOptional · stringUp to 50 characters. Empty or left out keeps it.
oauthAppOptional · stringOnly with sign-in tokens in
configthat came from the installation’s app:installation.
Secrets follow their address
A blank secret keeps its saved value only while the connection still points at the same place. Change a host, port, database, address or connection string, and send every saved secret again; otherwise you get 422 SECRETS_REQUIRED.
Any change to config clears the last test and error, and sets status to active (pending for a sign-in with no token). pieceId can’t change: make a new connection.
Sign-in tokens from elsewhere can be saved here as in Create a connection.
Responses
- 200OK
Updated. The answer holds no secret.
idisn’t a UUID, the body isn’t JSON, the name is missing or blank,authTypeis over 50 characters, or the change leaves a required field empty (details.fields).- 403
FORBIDDENThe token lacks the Write permission for connections.
The partner manages this connection through its own API, so it can’t be changed here.
- 404
NOT_FOUNDNo connection with this ID in the token’s workspace.
The change moves where the connection points (a host, server, port, database, address or connection string) and left a saved secret blank.
details.fieldsnames the secrets to send again. Nothing changed.With
test: true: the service refused the details (details.cause). Nothing was saved.Nothing changed. Try again.
- 503
NO_VERDICTWith
test: true: no answer came back (details.reason:no_worker,timeoutornot_served). Nothing was saved. - 503
UNAVAILABLEThe installation’s OAuth app for the service (
oauthApp: "installation") couldn’t be read. Nothing was saved. Try again.
Any call can also answer: 401 UNAUTHORIZED · 401 TOKEN_ENDED · 403 TOKEN_SURFACE_OFF · 403 FEATURE_OFF · 403 EMBED_NOT_ALLOWED · 403 EMBED_NOT_AVAILABLE · 403 ACCOUNT_SUSPENDED · 413 PAYLOAD_TOO_LARGE · 415 INVALID_CONTENT_TYPE · 429 RATE_LIMITED · 503 BUSY · 503 PAUSED · 503 SERVICE_UNAVAILABLE. See Errors.
Request
GORUNNER="https://api.gorunner.io"
GORUNNER_TOKEN="grt_…" # needs Write for connections
CONNECTION_ID="your-connection-id"
curl -X PUT "$GORUNNER/api/connections/$CONNECTION_ID" \
-H "Authorization: Bearer $GORUNNER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"config": {
"host": "db2.bakery.example",
"password": "…"
},
"test": true
}'const GORUNNER = "https://api.gorunner.io";
const TOKEN = process.env.GORUNNER_TOKEN;
const CONNECTION_ID = process.env.CONNECTION_ID;
const res = await fetch(
`${GORUNNER}/api/connections/${CONNECTION_ID}`,
{
method: "PUT",
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
config: {
host: "db2.bakery.example",
password: "…",
},
test: true,
}),
},
);
const { data } = await res.json();import os, requests
GORUNNER = "https://api.gorunner.io"
TOKEN = os.environ["GORUNNER_TOKEN"]
CONNECTION_ID = os.environ["CONNECTION_ID"]
res = requests.put(
f"{GORUNNER}/api/connections/{CONNECTION_ID}",
headers={"Authorization": f"Bearer {TOKEN}"},
json={
"config": {
"host": "db2.bakery.example",
"password": "…",
},
"test": True,
},
)
data = res.json()["data"]Response · 200 OK, shortened
{
"data": {
"id": "0f8b2c7e-4a51-4d3e-9b2a-6c1d2e3f4a5b",
"pieceId": "postgres",
"name": "Warehouse database",
"authType": "custom",
"status": "active",
"lastTestedAt": "2026-10-25T09:00:00Z",
"account": "warehouse@db2.bakery.example:5432/orders",
"workspaceId": "c41a7e02-9b3d-4f6a-8e15-7d2c0b9a4f68",
"orgId": "e9d2b6f1-3a7c-4d05-b8e4-1c6f2a9d7b30",
"createdBy": "5d8e1f3a-0b6c-4e2d-9f7a-1c3b5e8d2a40",
"createdAt": "2026-10-20T08:00:00Z",
"updatedAt": "2026-10-24T16:00:00Z"
}
}Every field
Body
nameOptional · stringNew label; trimmed; blank is a 400; at most 255 characters. Optional when
configis sent (absent keeps the stored name); required otherwise.authTypeOptional · stringOptional, at most 50 characters. An empty string or omission leaves the stored value unchanged.
configOptional · objectOPTIONAL, and its ABSENCE (
nullreads as absent) is the signal for a rename-only update (the verdict is kept). Sent, it is MERGED over the stored config: a key left out, or a string left blank, keeps the saved value;nullremoves a key; anything else replaces it. A sign-in’s tokens are kept unless named. Any config change resets the verdict:statusactive(orpendingfor a sign-in with no token),lastTestedAtandlastErrorcleared,accountrecomputed. A change that moves a where field (host, server, port, database, a URL, a connection string) must send every stored secret again, else 422SECRETS_REQUIRED(details.fieldsnames their keys,details.changedthe where keys).testOptional · booleanTest the merged config first, as on create: refused → 422
CONNECTION_TEST_FAILED, no verdict → 503NO_VERDICT, nothing changed.oauthAppOptional · stringOnly with OAuth2 tokens in
config(anaccessToken): they came from the installation’s app for this service, which refreshes them. Refused without tokens, withclientIdinconfig, or when the installation has no app for the service.One of
installation.
Response · 200 OK
dataobjectA stored credential set for one app. The encrypted credential itself is never present in this object — the model tags it
json:"-"— so there is no field here, and no endpoint anywhere, that returns a secret you wrote.idUUIDThe connection’s id. This is the value a workflow step or trigger carries as
connectionIdto use these credentials.pieceIdstringThe app these credentials belong to (e.g.
seatable,postgres,googlesheets, or the genericoauth2). Fixed at creation and not changeable.namestringHuman label. Not unique.
authTypestringFree-text label recording the auth shape. Defaults to
api_keywhen not supplied at creation. Conventionally one of the app’sauth.typevalues, but NOT validated against the app — treat it as advisory.statusstringThe last known verdict on these credentials.
active= created normally, or the last test passed.pending= an OAuth2 connection that has not completed the authorization flow (no access token yet).unverified= the last test proved nothing because the app has no connection test; credentials are checked on first real use.error= the last test was refused by the provider.expired= a refresh was refused for good — the provider rejected the stored grant or the client (revoked, aged out), or the OAuth app that issued the tokens was replaced or removed; signing in again (Re-authorize) mends it. The test endpoint (andtest: trueon create or update), the OAuth2 sign-in and a refused refresh set it; an update that sendsconfigresets it toactive(pendingfor a sign-in with no token); a rename leaves it.One of
active,pending,unverified,error,expired.lastTestedAttimeWhen the connection was last tested. Absent if never tested.
tokenExpiresAttimeOAuth2 access-token expiry, when known. Refresh happens automatically at run time; there is no manual refresh call.
refreshablebooleanThe stored config carries a refresh token, so
tokenExpiresAtis when the access token is next RENEWED (on use), not when the connection ends. False for pasted access tokens and API keys. A connection whose refresh the provider refuses for good is markedstatus: expiredon the next refresh attempt and needs signing in again.managedBystringPresent only on a connection the installation’s partner manages through the embed API. It is read-only here: update, delete and the OAuth2 sign-in answer 403
MANAGED_CONNECTION; test and replace stay open.One of
partner.workspaceIdUUIDOwning workspace. Populated on the create’s answer; the all-zero UUID on the list, the single read and an update’s answer, which read the row the way the list does and do not select it.
orgIdUUIDOwning organization. Same caveat as
workspaceId: all-zero except in the create’s answer.createdByUUIDThe user who created it. Absent when no person did (the partner’s, a machine’s, rows from before creators were recorded).
createdAttimeupdatedAttimeaccountstringWho or what the credential is, never a secret: the Google address a test names,
user@host(with port and database) from a typed credential’s non-secret fields, a SeaTable base’s name and server. Shown to every reader. Absent until known.createdByNamestringThe creator’s name (else their address), only while they are a member of the organization.
createdByMemberbooleanFalse once the creator is no longer a member of the organization. Absent with
createdBy.lastErrorobjectThe last failure that still stands. Written by a failed test, a refused refresh (
expired), and a run’s or poll’s definite refusal; a run’s 403 is kept as news (cause: forbidden) without changingstatus. Cleared by a working test, a sign-in, a config change, and the next run or poll that uses the connection and works.attimesourcestringOne of
test,run,trigger,refresh,signin.causestringrefused— the service refused the credential (401, SMTP 535, Postgres 28P01, MySQL 1045, …);expired— a refresh was refused for good;server— the server could not be reached;forbidden— a 403, news only;other.One of
refused,expired,server,forbidden,other.messagestringThe service’s own words, masked of the step’s secrets, at most 1,000 characters.
runIdUUIDworkflowIdUUIDworkflowNamestringWhile the workflow exists.
lastUseobjectThe newest use the audit trail records (its
connection.decryptrows). Absent when the trail has none.attimekindstringOne of
run,trigger,test,editor,signin.runIdUUIDworkflowIdUUIDworkflowNamestringbyNamestringThe person, for a test, the builder or a sign-in, while a member of the organization.
oauthClientstringFor a connection that signs in:
managed— the installation’s app;byo— its own client id;pasted— an access token with no refresh token, which cannot renew itself.One of
managed,byo,pasted.lastSignInAttimeWhen a sign-in last stored tokens.
expiresAttimeWhen the connection stops working with no way to renew:
tokenExpiresAtof a connection that is notrefreshable. Absent for a refreshable one and when unknown.testobjectOnly on the answer of a create or a change sent with
test: true: the test that let it be saved.successbooleanAlways
truehere: a refused test saves nothing and is a 422.messagestringThe app’s own words.
unverifiedbooleanPresent and true when the app cannot be tested without running a real step: saved, and nothing was proven.