AI Providers API Documentation
A library’s searches in plain language, and the embedding of its lyrics, run through the library’s own accounts with AI providers and are charged to them. These endpoints hold the keys to those accounts. A library needs at least one key before it can be given a chat model or an embedding model in its settings.
Every endpoint here, the GETs included, takes the admin role; the changes also take the catalog_admin scope. A key is write-only. It is taken and never given back; what is given of it is api_key_hint, its last four characters.
A provider is addressed by its name: openai, deepseek or grok.
Endpoints
Retrieve the providers the library holds keys for, by name, and every provider the server knows. Not paged.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
Response
{
"ai_providers": [
{
"id": "openai",
"provider": "openai",
"display_name": "OpenAI",
"api_key_hint": "…jBWE",
"uri_base": null,
"created_at": "2026-09-17T17:53:24.850-05:00",
"updated_at": "2026-09-17T17:53:24.850-05:00",
"url": "https://app.spondulix.ai/api/v1/libraries/2/ai_providers/openai"
}
],
"available": [
{ "provider": "openai", "display_name": "OpenAI" },
{ "provider": "deepseek", "display_name": "Deepseek" },
{ "provider": "grok", "display_name": "Grok (x.ai)" }
]
}
Response Fields
| Field |
Type |
Description |
| ai_providers |
array |
The providers the library holds keys for |
| id, provider |
string |
Name of the provider, which is what addresses it |
| display_name |
string |
What the provider is called |
| api_key_hint |
string |
The last four characters of the key, after an ellipsis |
| uri_base |
string | null |
Address of the provider’s API, when it is not the usual one |
| created_at |
string |
Timestamp of when the key was added |
| updated_at |
string |
Timestamp of when the key was last changed |
| url |
string |
URL of the provider |
| available |
array |
Every provider the server knows, for choosing one |
HTTP Response Codes
| Code |
Description |
200 OK |
Successful request |
403 Forbidden |
Your role is below admin |
404 Not Found |
Invalid library ID |
Add a provider’s key to the library.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
Request Body
Wrap the fields in an ai_provider key.
| Field |
Type |
Description |
Required |
| provider |
string |
openai, deepseek or grok. One key per provider per library. |
Yes |
| api_key |
string |
The key. Never returned. |
Yes |
| uri_base |
string |
Address of the provider’s API, when it is not the usual one. http or https. |
No |
{
"ai_provider": {
"provider": "openai",
"api_key": "sk-..."
}
}
Response
Returns the provider as shown in the list response, with the key’s hint in place of the key.
HTTP Response Codes
| Code |
Description |
201 Created |
Successful creation |
403 Forbidden |
Your role is below admin, or the token does not carry catalog_admin |
404 Not Found |
Invalid library ID |
422 Unprocessable Content |
provider “is not included in the list” or “has already been taken”; api_key “can’t be blank”; uri_base “is invalid” |
Retrieve one provider.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| provider |
string |
Name of the provider |
Yes |
Response
{
"id": "openai",
"provider": "openai",
"display_name": "OpenAI",
"api_key_hint": "…jBWE",
"uri_base": null,
"created_at": "2026-09-17T17:53:24.850-05:00",
"updated_at": "2026-09-17T17:53:24.850-05:00",
"url": "https://app.spondulix.ai/api/v1/libraries/2/ai_providers/openai"
}
HTTP Response Codes
| Code |
Description |
200 OK |
Successful request |
403 Forbidden |
Your role is below admin |
404 Not Found |
Invalid library ID, or no key for that provider |
Replace the key, the address or both. PATCH works the same way. A blank api_key leaves the stored key as it is. The provider’s name cannot be changed.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| provider |
string |
Name of the provider |
Yes |
Request Body
| Field |
Type |
Description |
Required |
| api_key |
string |
The new key |
No |
| uri_base |
string |
Address of the provider’s API |
No |
Response
Returns the updated provider.
HTTP Response Codes
| Code |
Description |
200 OK |
Successful update |
403 Forbidden |
Your role is below admin, or the token does not carry catalog_admin |
404 Not Found |
Invalid library ID, or no key for that provider |
422 Unprocessable Content |
Invalid request (see response body for details) |
Remove the provider’s key. The library settings that named the provider are cleared with it: a chat or embedding provider and model set to this provider go to null.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| provider |
string |
Name of the provider |
Yes |
Response
(no response body)
HTTP Response Codes
| Code |
Description |
204 No Content |
Successful deletion |
403 Forbidden |
Your role is below admin, or the token does not carry catalog_admin |
404 Not Found |
Invalid library ID, or no key for that provider |