Gen3 Gt Api Example Curl Commands - GT-Edge-AI/GT-AI-OS GitHub Wiki
Use these copy-paste curl examples to smoke-test GT API routes. Start with discovery (GET /v1/models, GET /v1/upload-targets), run the golden-path sequence when you need conversation continuity and uploads, then poll GET /v1/files/{id} (alias GET /v1/uploads/{id}) until status is ready or failed.
GT API mirrors OpenAI-shaped paths under /api/tenant/v1/* but uses separate key purposes (inference, upload, conversation), conversation headers, dataset uploads, and asynchronous file processing.
OpenAPI source of truth: gt-ai-os/docs/reference/GT3-TENANT-EXTERNAL-API-OPENAPI.yaml.
| Route family | Typical key purpose | Placeholder |
|---|---|---|
| Stateless chat, embeddings, audio, images | Inference | <YOUR_INFERENCE_API_KEY> |
| Conversation create, follow-up chat, conversation uploads | Conversation | <YOUR_CONVERSATION_API_KEY> |
| Dataset uploads, upload-target discovery, file status (upload key) | Upload | <YOUR_UPLOAD_API_KEY> |
Issue keys from GT API → API Keys using the presets that match your integration. Allowlist published inference and dataset names before testing.
Run these steps in one shell session when validating inference, persisted conversation continuity, both upload paths, and file polling. Replace every placeholder first.
# 0) Optional: create local sample upload files if missing
DEMO_DIR="$HOME/gt-api-demo-uploads"
mkdir -p "$DEMO_DIR"
[ -f "$DEMO_DIR/sample-conversation-upload.txt" ] || printf "%s\n" "Sample conversation upload file." > "$DEMO_DIR/sample-conversation-upload.txt"
[ -f "$DEMO_DIR/sample-dataset-upload.txt" ] || printf "%s\n" "Sample dataset upload file." > "$DEMO_DIR/sample-dataset-upload.txt"
# 1) Discover published model aliases
curl -sS \
-H "Authorization: Bearer <YOUR_INFERENCE_API_KEY>" \
"https://<tenant-host>/api/tenant/v1/models" | jq .
# 2) Stateless chat (inference key)
curl -sS \
-H "Authorization: Bearer <YOUR_INFERENCE_API_KEY>" \
-H "Content-Type: application/json" \
"https://<tenant-host>/api/tenant/v1/chat/completions" \
-d '{
"model": "<PUBLISHED_MODEL_ALIAS>",
"messages": [{ "role": "user", "content": "Reply with exactly: Stateless API demo ok." }]
}' | jq .
# 3) Create conversation and send first message (conversation key)
CONV_ID="$(curl -sS -i \
-H "Authorization: Bearer <YOUR_CONVERSATION_API_KEY>" \
-H "Content-Type: application/json" \
"https://<tenant-host>/api/tenant/v1/conversations" \
-d '{
"model": "<PUBLISHED_MODEL_ALIAS>",
"title": "Sequential API demo"
}' | tee /tmp/gt-conversation-create.out | awk -F': ' 'tolower($1)=="x-gt-conversation-id"{gsub("\r","",$2); print $2}')
curl -sS \
-H "Authorization: Bearer <YOUR_CONVERSATION_API_KEY>" \
-H "Content-Type: application/json" \
-H "X-GT-Conversation-Id: $CONV_ID" \
"https://<tenant-host>/api/tenant/v1/chat/completions" \
-d '{
"model": "<PUBLISHED_MODEL_ALIAS>",
"messages": [{ "role": "user", "content": "Remember the codeword: pineapple." }]
}' | jq .
# 4) Follow-up message in the same conversation
curl -sS \
-H "Authorization: Bearer <YOUR_CONVERSATION_API_KEY>" \
-H "Content-Type: application/json" \
-H "X-GT-Conversation-Id: $CONV_ID" \
"https://<tenant-host>/api/tenant/v1/chat/completions" \
-d '{
"model": "<PUBLISHED_MODEL_ALIAS>",
"messages": [{ "role": "user", "content": "What codeword did I ask you to remember?" }]
}' | jq .
# 5) Conversation-scoped upload
curl -sS -i \
-H "Authorization: Bearer <YOUR_CONVERSATION_API_KEY>" \
-H "X-GT-Conversation-Id: $CONV_ID" \
-F "file=@$HOME/gt-api-demo-uploads/sample-conversation-upload.txt;type=text/plain;filename=sample-conversation-upload.txt" \
"https://<tenant-host>/api/tenant/v1/conversations/files"
# 6) Dataset upload (upload key)
curl -sS -i \
-H "Authorization: Bearer <YOUR_UPLOAD_API_KEY>" \
-F "file=@$HOME/gt-api-demo-uploads/sample-dataset-upload.txt;type=text/plain;filename=sample-dataset-upload.txt" \
"https://<tenant-host>/api/tenant/v1/datasets/<DATASET_PUBLIC_ALIAS>/files"
# 7) Poll file status (replace <FILE_ID> with id from step 5 or 6)
curl -sS \
-H "Authorization: Bearer <YOUR_UPLOAD_API_KEY>" \
"https://<tenant-host>/api/tenant/v1/files/<FILE_ID>" | jq .AUTH Authorization: Bearer gtak_...
Every GT API route stays private behind tenant-local bearer-key authentication.
Key: Use the key purpose that matches the route (inference, upload, or conversation).
Prerequisites
- Issue a GT API key from the tenant GT API workspace with the scopes and allowlists required for the route you are testing.
Replace in this example
-
<YOUR_INFERENCE_API_KEY>,<YOUR_CONVERSATION_API_KEY>, or<YOUR_UPLOAD_API_KEY>— bearer secret for the matching key purpose. -
https://<tenant-host>/api/tenant— tenant origin plus the GT API proxy prefix.
Expected outcome
- Requests without a valid bearer token return
401.
Notes
- Keys are shown in plaintext once and then stored only as hashes.
- What a caller can see depends on the key scopes, allowlists, and any linked conversation binding.
- Inference keys may attach prompt guardrail modules and additional prompt text; GT applies those layers server-side together with the configured agent (or raw-model routing policy) for allowed calls.
Authorization: Bearer <YOUR_GT_API_KEY>
Content-Type: application/jsonGET /v1/models
Returns only the published inference aliases the presented key is allowed to discover.
Key: Inference key with inference:chat (and other inference scopes as needed).
Prerequisites
- Publish at least one inference target in GT API → Published Endpoints.
- Allowlist that published name on the inference key you will use for chat or other inference routes.
Replace in this example
-
<YOUR_INFERENCE_API_KEY>— inference key that may discover models. - Pick a returned
idvalue for<PUBLISHED_MODEL_ALIAS>in later chat or modality examples.
Expected outcome
- HTTP
200with a JSON list whosedata[].identries are the published names this key may use inmodel.
Notes
- Each entry is a published inference name callers put in
model, not a bearer secret. - The list can include agent-backed aliases and operator-published raw-model catalog names when the key includes
inference:chat; both are filtered by the presenting key’s allowlists before they appear. - Raw-model catalog names appear for stateless chat discovery only; they do not unlock embeddings, audio, or image routes.
curl -sS \
-H "Authorization: Bearer <YOUR_INFERENCE_API_KEY>" \
"https://<tenant-host>/api/tenant/v1/models"GET /v1/upload-targets
Returns dataset aliases and conversation-upload targets the presented key may write to.
Key: Upload key (datasets:write) or conversation key that inherits upload access.
Prerequisites
- Create or identify the dataset targets you want external upload keys to reach.
- Issue an upload key (or conversation key with linked upload access) allowlisted to those targets.
Replace in this example
-
<YOUR_UPLOAD_API_KEY>or<YOUR_CONVERSATION_API_KEY>— key that may discover upload targets. - Pick a dataset
publicAliasfor<DATASET_PUBLIC_ALIAS>in dataset upload examples.
Expected outcome
- HTTP
200with upload targets filtered to the presenting key. - Conversation upload targets may note that
X-GT-Conversation-Idis required at request time.
Notes
- Use this before guessing dataset alias path segments in
/v1/datasets/{alias}/files. - Conversation-facing keys may expose conversation-upload targets after least-privilege binding to linked upload keys.
curl -sS \
-H "Authorization: Bearer <YOUR_UPLOAD_API_KEY>" \
"https://<tenant-host>/api/tenant/v1/upload-targets"POST /v1/embeddings
Runs an OpenAI-compatible embeddings request using a published agent alias while GT resolves the tenant embedding model behind the trust boundary.
Key: Inference key with inference:embed for the allowlisted alias.
Prerequisites
- Publish an agent alias the key may use for embeddings.
- Grant
inference:embedon the inference key and allowlist the alias.
Replace in this example
-
<YOUR_INFERENCE_API_KEY>— embed-scoped inference key. -
<PUBLISHED_MODEL_ALIAS>— published agent alias fromGET /v1/models(raw-model catalog names are not valid here).
Expected outcome
- HTTP
200with an OpenAI-shaped embeddings payload (data[].embedding).
Notes
- The presented key must include
inference:embedfor the allowlisted name. - GT resolves vectors through the tenant trust boundary; callers still pass a published agent alias in
model. - Use
encoding_format: "float"orencoding_format: "base64"depending on what the client library expects.
curl -sS \
-H "Authorization: Bearer <YOUR_INFERENCE_API_KEY>" \
-H "Content-Type: application/json" \
"https://<tenant-host>/api/tenant/v1/embeddings" \
-d '{
"model": "<PUBLISHED_MODEL_ALIAS>",
"input": ["Sample text for embedding"]
}'POST /v1/chat/completions
Runs an OpenAI-compatible chat request using a published model alias.
Key: Inference key with inference:chat (stateless) or conversation key when using X-GT-Conversation-Id.
Prerequisites
- Discover an allowed published name with
GET /v1/models. - For stateless chat, use an inference key with
inference:chatand no conversation header.
Replace in this example
-
<YOUR_INFERENCE_API_KEY>— inference key for stateless chat (or<YOUR_CONVERSATION_API_KEY>when a conversation header is present). -
<PUBLISHED_MODEL_ALIAS>— published name fromGET /v1/models.
Expected outcome
- HTTP
200withchoices[0].message.contentcontaining the assistant reply.
Notes
- Send the user content you want the model to answer; for agent aliases, the configured agent supplies its base prompt, and the key may add prompt modules or extra prompt text on top.
-
modelmust be a published name this key may use: an agent alias or a published raw-model catalog name (raw-model aliases are stateless chat only). - Without
X-GT-Conversation-Id, chat completions stay stateless and do not create a persisted GT conversation. - Clients that need GT-managed continuity should call
POST /v1/conversationsfirst, then reuse the returnedX-GT-Conversation-Idheader on follow-up chat and upload requests. - Conversation-facing keys may inherit their runtime allowlists from linked inference and upload keys.
curl -sS \
-H "Authorization: Bearer <YOUR_INFERENCE_API_KEY>" \
-H "Content-Type: application/json" \
"https://<tenant-host>/api/tenant/v1/chat/completions" \
-d '{
"model": "<PUBLISHED_MODEL_ALIAS>",
"messages": [
{ "role": "user", "content": "Reply with a one-sentence summary of the request." }
]
}'POST /v1/audio/transcriptions
Runs OpenAI-compatible speech-to-text using the published agent alias and that agent's configured STT model.
Key: Inference key with inference:transcribe for the allowlisted alias.
Prerequisites
- Publish an agent alias with speech-to-text settings that match your tenant policy.
- Grant
inference:transcribeon the inference key.
Replace in this example
-
<YOUR_INFERENCE_API_KEY>— inference key with transcribe scope. -
<PUBLISHED_MODEL_ALIAS>— published agent alias fromGET /v1/models. -
<LOCAL_FILE_PATH>— local audio file path (for example a .wav file that exists on disk).
Expected outcome
- HTTP
200with transcript text in the OpenAI-compatible response body.
Notes
- The presented key must include
inference:transcribefor the allowlisted alias. - The public
modelstays an exposed agent alias; GT resolves the underlying STT model behind the tenant trust boundary.
curl -sS \
-H "Authorization: Bearer <YOUR_INFERENCE_API_KEY>" \
-F "model=<PUBLISHED_MODEL_ALIAS>" \
-F "file=@<LOCAL_FILE_PATH>" \
"https://<tenant-host>/api/tenant/v1/audio/transcriptions"POST /v1/audio/speech
Runs OpenAI-compatible text-to-speech using the published agent alias and that agent's configured TTS model.
Key: Inference key with inference:speech for the allowlisted alias.
Prerequisites
- Publish an agent alias with text-to-speech settings that match your tenant policy.
- Grant
inference:speechon the inference key.
Replace in this example
-
<YOUR_INFERENCE_API_KEY>— inference key with speech scope. -
<PUBLISHED_MODEL_ALIAS>— published agent alias fromGET /v1/models.
Expected outcome
- HTTP
200returning synthesized audio bytes (commonly written to a local file with curl-o).
Notes
- The presented key must include
inference:speechfor the allowlisted alias. - Agent speech settings can supply the default voice and output format when the request omits them.
curl -sS \
-H "Authorization: Bearer <YOUR_INFERENCE_API_KEY>" \
-H "Content-Type: application/json" \
"https://<tenant-host>/api/tenant/v1/audio/speech" \
-d '{
"model": "<PUBLISHED_MODEL_ALIAS>",
"input": "Read the summary aloud."
}'POST /v1/images/generations
Runs OpenAI-compatible image generation using the published agent alias and that agent's configured image model.
Key: Inference key with inference:image for the allowlisted alias.
Prerequisites
- Publish an image-capable agent alias.
- Grant
inference:imageon the inference key.
Replace in this example
-
<YOUR_INFERENCE_API_KEY>— inference key with image scope. -
<PUBLISHED_MODEL_ALIAS>— published agent alias fromGET /v1/models.
Expected outcome
- HTTP
200with generated image payload fields in the OpenAI-compatible response.
Notes
- The presented key must include
inference:imagefor the allowlisted alias. - Dataset
vision_modelis unrelated here; it remains an ingestion/indexing setting, not a runtime generation selector.
curl -sS \
-H "Authorization: Bearer <YOUR_INFERENCE_API_KEY>" \
-H "Content-Type: application/json" \
"https://<tenant-host>/api/tenant/v1/images/generations" \
-d '{
"model": "<PUBLISHED_MODEL_ALIAS>",
"prompt": "Generate a simple diagram for the scenario."
}'POST /v1/conversations
Creates a GT-managed conversation id for clients that want persisted chat continuity and conversation-scoped uploads.
Key: Conversation key (often linked to reusable inference and upload keys).
Prerequisites
- Issue a conversation-purpose key (or use the conversation preset) with linked inference access.
- Discover an allowed published model name with
GET /v1/modelsusing the linked inference key or the conversation key’s inherited allowlists.
Replace in this example
-
<YOUR_CONVERSATION_API_KEY>— conversation key. -
<PUBLISHED_MODEL_ALIAS>— published inference name the conversation may use.
Expected outcome
- HTTP
201(or200per deployment) with response headerX-GT-Conversation-Idset to the persisted conversation id. - Save that header value as
<GT_CONVERSATION_ID>for follow-up chat and conversation uploads.
Notes
- This is a GT-specific extension; ordinary OpenAI-compatible clients can stay on stateless
/v1/chat/completions. -
modelmust be a published inference name that the presented key is allowed to use (agent alias or raw-model catalog name). - Use
curl -i(or-D -) so response headers are visible; the conversation id is returned asX-GT-Conversation-Id, not only in the JSON body.
CONV_ID="$(curl -sS -i \
-H "Authorization: Bearer <YOUR_CONVERSATION_API_KEY>" \
-H "Content-Type: application/json" \
"https://<tenant-host>/api/tenant/v1/conversations" \
-d '{
"model": "<PUBLISHED_MODEL_ALIAS>",
"title": "External API test thread"
}' | awk -F': ' 'tolower($1)=="x-gt-conversation-id"{gsub("\r","",$2); print $2}')
echo "CONV_ID=$CONV_ID"POST /v1/datasets/{alias}/files
Accepts multipart file uploads for a static dataset target allowed by the presented upload key.
Key: Upload key with datasets:write allowlisted to the dataset alias.
Prerequisites
- Discover an allowed dataset alias with
GET /v1/upload-targets. - Prepare a local file path that exists on the machine running curl.
Replace in this example
-
<YOUR_UPLOAD_API_KEY>— upload key with dataset write access. -
<DATASET_PUBLIC_ALIAS>— dataset public alias fromGET /v1/upload-targets. -
<LOCAL_FILE_PATH>— local file path. On macOS, prefer a literal path such as$HOME/.../sample-upload.txtinside the-Fargument instead of a shell variable inside-F.
Expected outcome
- HTTP
201with JSON containing fileid— save it as<FILE_ID>for status polling. - Initial
status/processing_statusis commonlypendingorprocessing.
Notes
- Use this for direct dataset ingestion flows.
- The key must carry
datasets:writeand be allowed to reach that dataset target. - The
{alias}path segment is the published dataset alias, not an internal database id.
curl -sS -i \
-H "Authorization: Bearer <YOUR_UPLOAD_API_KEY>" \
-F "file=@<LOCAL_FILE_PATH>;type=text/plain;filename=sample-upload.txt" \
"https://<tenant-host>/api/tenant/v1/datasets/<DATASET_PUBLIC_ALIAS>/files"POST /v1/conversations/files
Accepts multipart file uploads that auto-create and attach a conversation-scoped dataset rather than targeting a fixed dataset alias.
Key: Conversation key (or key with conversation-scoped upload permission).
Prerequisites
- Create a conversation first with
POST /v1/conversationsand captureX-GT-Conversation-Id. - Prepare a local file path that exists on the machine running curl.
Replace in this example
-
<YOUR_CONVERSATION_API_KEY>— conversation key used for the active thread. -
<GT_CONVERSATION_ID>— value from theX-GT-Conversation-Idresponse header. -
<LOCAL_FILE_PATH>— local file path.
Expected outcome
- HTTP
201with JSON fileidand echo ofconversationId. - Poll
GET /v1/files/{id}until processing completes when downstream RAG depends on the upload.
Notes
- Requires
X-GT-Conversation-Id. - The key must allow conversation-scoped uploads, either directly or through a linked upload key.
- The upload creates or reuses the conversation upload dataset that stays attached to the active chat scope.
curl -sS -i \
-H "Authorization: Bearer <YOUR_CONVERSATION_API_KEY>" \
-H "X-GT-Conversation-Id: <GT_CONVERSATION_ID>" \
-F "file=@<LOCAL_FILE_PATH>;type=text/plain;filename=sample-upload.txt" \
"https://<tenant-host>/api/tenant/v1/conversations/files"GET /v1/files/{fileId}
Returns asynchronous processing state for a previously uploaded file.
Key: Same upload or conversation key that performed the upload (must be allowed to read the file).
Prerequisites
- Complete a dataset or conversation upload and copy the returned file
id.
Replace in this example
-
<YOUR_UPLOAD_API_KEY>or<YOUR_CONVERSATION_API_KEY>— key that created the upload. -
<FILE_ID>— file id from the upload response JSON.
Expected outcome
- HTTP
200while processing advances through stages such asqueued,processing, thenreadyorfailed. - Alias route:
GET /v1/uploads/{id}returns the same status envelope.
Notes
- Use this after either dataset or conversation uploads when downstream processing is asynchronous.
- Stop polling when
statusisready(success) orfailed(inspectfailureReason).
curl -sS \
-H "Authorization: Bearer <YOUR_UPLOAD_API_KEY>" \
"https://<tenant-host>/api/tenant/v1/files/<FILE_ID>"HEADER X-GT-Conversation-Id
Carries the GT conversation id that ties follow-up chat turns and conversation-scoped uploads together.
Key: Conversation key on chat and upload routes that participate in the same thread.
Prerequisites
- Run
POST /v1/conversationsfirst and captureX-GT-Conversation-Id. - Keep
/tmp/gt-conversation-create.outor exportCONV_IDin the same shell session while testing.
Replace in this example
-
<YOUR_CONVERSATION_API_KEY>— conversation key. -
<GT_CONVERSATION_ID>— persisted conversation id from the create response header. -
<PUBLISHED_MODEL_ALIAS>— same published model used when the conversation was created.
Expected outcome
- Follow-up
POST /v1/chat/completionsresponses reflect prior turns in the persisted conversation. - Conversation uploads accept the same header value.
Notes
- Required for
/v1/conversations/files. - Optional on
/v1/chat/completions; when present, GT API uses the existing persisted conversation instead of stateless request history only. - Returned by
POST /v1/conversationsso clients can opt into persisted chat continuity explicitly.
curl -sS \
-H "Authorization: Bearer <YOUR_CONVERSATION_API_KEY>" \
-H "X-GT-Conversation-Id: <GT_CONVERSATION_ID>" \
-H "Content-Type: application/json" \
"https://<tenant-host>/api/tenant/v1/chat/completions" \
-d '{
"model": "<PUBLISHED_MODEL_ALIAS>",
"messages": [
{ "role": "user", "content": "Continue in the same conversation context." }
]
}'