Ana içeriğe geç

Test LLM Provider Connection

Endpoint

POST /apiops/projects/{projectName}/llm-providers/{providerName}/test-connection/

Authentication

Requires a Personal API Access Token.

Authorization: Bearer YOUR_TOKEN

Request

Headers

HeaderValueRequired
AuthorizationBearer {token}Yes
Content-Typeapplication/jsonOnly if a body is sent

Path Parameters

ParameterTypeRequiredDescription
projectNamestringYesProject name
providerNamestringYesLLM provider name (must already exist)

Query Parameters

None

Request Body

Optional. This is the one write-shaped APIops endpoint whose body may be omitted entirely.

  • Omitted / empty body: the currently stored provider (as persisted, with its stored encrypted credential) is tested exactly as-is.
  • Body supplied: it is a ConnectionConfigLlm object and, because the type carries the connection-config polymorphic discriminator, it must include "_class": "llm". name may be left blank (falls back to the providerName path value) but if present must match it. Blank apiKey / apiSecret / serviceAccountJson fields are backfilled from the stored provider's encrypted values — but only if the connection target has not changed (see the secret-exfiltration guard below).

Full JSON Body Example — testing modified settings

{
"_class": "llm",
"name": "deepseek-primary",
"providerType": "DEEPSEEK",
"endpoint": "https://api.deepseek.com/v1",
"authScheme": "BEARER",
"authHeaderName": "Authorization",
"apiKey": "sk-a-different-key-to-try",
"deploymentType": "CLOUD"
}

Request Body Fields

Same shape as Create LLM Provider. The fields that participate in the secret-exfiltration guard are called out below:

FieldTypeRole in the guard
endpointstringPart of the "connection target" — must be unchanged for a blank secret to be reused
authSchemestringPart of the "connection target"
authHeaderNamestringPart of the "connection target"
providerTypestringPart of the "connection target"
deploymentTypestringPart of the "connection target"
apiKey / apiSecret / serviceAccountJsonstringBackfilled from the stored value only when the target above is unchanged; otherwise must be supplied in plaintext

Notes

  • Body is fully optional — send {} or no body at all to test the provider exactly as stored.
  • _class: "llm" is mandatory whenever a body is sent.

Response

The test always returns 200 OK when the request itself is valid; the connectivity outcome is carried in deploymentResult.success — a connectivity/auth failure is success: false with the reason in detail, not an HTTP error.

Success Response (200 OK)

{
"status": "SUCCESS",
"deploymentResult": {
"success": true,
"envName": "apimanager",
"detail": "LLM provider connection test successful"
}
}

Failed connectivity (still 200 OK, status: SUCCESS, but deploymentResult.success: false):

{
"status": "SUCCESS",
"deploymentResult": {
"success": false,
"envName": "apimanager",
"detail": "401 Unauthorized from provider endpoint"
}
}

Response Fields

FieldTypeDescription
statusstringEnvelope status — SUCCESS when the test was executed (FAILURE only for request errors)
deploymentResultobjectResult of the in-process connectivity probe
deploymentResult.successbooleantrue if the provider accepted the test call
deploymentResult.envNamestringAlways apimanager — the test runs in-process on the Manager, no worker round-trip
deploymentResult.detailstring"LLM provider connection test successful" on success, or the raw provider/transport failure reason on failure

Error Response (400 Bad Request) — Not Found / Validation

{
"status": "FAILURE",
"resultMessage": "LLM provider (name: deepseek-primary) was not found!"
}

Error Response (400 Bad Request) — Secret-Exfiltration Guard

Returned when a body is supplied that changes the connection target (endpoint/authScheme/authHeaderName/providerType/deploymentType) while leaving a secret field blank:

{
"status": "FAILURE",
"resultMessage": "Connection target changed — re-enter the credential before testing"
}

Error Response (401 Unauthorized)

{
"status": "FAILURE",
"resultMessage": "Token is not valid!"
}

cURL Example

Test the stored provider as-is (no body):

curl -X POST \
"https://demo.apinizer.com/apiops/projects/MyProject/llm-providers/deepseek-primary/test-connection/" \
-H "Authorization: Bearer YOUR_TOKEN"

Test with a different API key against the same target:

curl -X POST \
"https://demo.apinizer.com/apiops/projects/MyProject/llm-providers/deepseek-primary/test-connection/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"_class": "llm",
"name": "deepseek-primary",
"providerType": "DEEPSEEK",
"endpoint": "https://api.deepseek.com/v1",
"authScheme": "BEARER",
"authHeaderName": "Authorization",
"apiKey": "sk-a-different-key-to-try",
"deploymentType": "CLOUD"
}'

Permissions

  • User must have AI_DEVELOPMENT + MANAGE permission in the project

Notes and Warnings

  • Body Is Optional: Unlike every other write endpoint in this API, the body may be omitted. Omitting it tests the stored provider exactly as persisted (its stored, encrypted credential is decrypted in-process for the call — never returned).
  • Secret-Exfiltration Guard (critical): When a body is supplied, a blank apiKey/apiSecret/serviceAccountJson is normally backfilled from the stored provider's credential — but only if endpoint, authScheme, authHeaderName, providerType and deploymentType are all unchanged from the stored provider. If any of those changed while a secret is left blank, the request is rejected with credentialReentryRequired instead of silently sending the stored credential to a (possibly attacker-controlled) new endpoint. To test a new endpoint, supply the real secret explicitly.
  • No Persistence: This endpoint never saves the tested configuration — use Create LLM Provider or Update LLM Provider to persist changes after a successful test.
  • Manager-Side Only: The probe runs in-process on the Manager (envName: "apimanager"); it is not sent through a gateway worker, so it does not reflect worker-side network policy.
  • Outcome In The Body: A failed connectivity test still returns 200 OK with status: "SUCCESS" — always check deploymentResult.success.