ANTARESby EMT Aerospace Technologies S.r.l.
Apri menu

ANTARES API

Riferimento dell'API ANTARES

Integra i modelli offerti da ANTARES nei tuoi server, con credito prepagato.

Panoramica

L'API di ANTARES dà ai tuoi server accesso ai modelli offerti da ANTARES. È prepagata: aggiungi credito nella console per sviluppatori e ogni richiesta viene pagata da quel saldo, separato da qualsiasi abbonamento alla chat di ANTARES.

URL di base: https://emtantares.com/api/developer. Tutti gli endpoint sono sotto /v1 e scambiano JSON; gli importi sono micro-euro interi (milionesimi di euro) inviati come stringhe, ad esempio "charged_micros": "41".

Prima che il modello parta, la richiesta trattiene il suo addebito massimo possibile: l'input e max_tokens al prezzo del modello. Quando il modello ha risposto, viene addebitato solo l'utilizzo misurato e il resto torna subito disponibile nel saldo. Ogni progetto ha un limite di spesa e può avere un limite mensile; una richiesta che potrebbe superarli viene rifiutata prima che parta qualsiasi cosa.

MetodoPercorsoAutorizzazione della chiave
POST/v1/messagesmessages:write
POST/v1/messages/count_tokensmessages:write
GET/v1/modelsany
GET/v1/models/{model_id}any
GET/v1/requests/{idempotency_key}any
POST/v1/chat/completionsmessages:write
POST/v1/responsesresponses:write

Autenticazione e chiavi

Crea un progetto e una chiave API nella console per sviluppatori. Il segreto (ant_sk_v1_…) viene mostrato una sola volta: conservalo nel gestore dei segreti del tuo server. Invialo come x-api-key: <chiave> oppure come Authorization: Bearer <chiave>; se li invii entrambi devono contenere la stessa chiave.

Le chiavi sono solo per i server. Una richiesta con l'intestazione Origin, cioè ogni richiesta fatta da una pagina web, viene rifiutata con server_side_only: non c'è mai motivo di mettere una chiave in un browser o in un'app mobile.

  • messages:write consente Messages, il conteggio dei token e le chat completions; responses:write consente il primo endpoint di testo; models:read elenca solo i modelli. Qualsiasi chiave attiva può elencare i modelli e leggere l'esito delle proprie richieste.
  • Le chiavi scadono dopo la validità che scegli e si possono revocare in qualsiasi momento; archiviare un progetto revoca definitivamente tutte le sue chiavi.
  • L'account deve avere l'e-mail verificata e aver accettato i termini in vigore.

Invia antares-version: 2026-09-24 per fissare la versione per cui hai scritto il codice. Senza, risponde la versione più recente; una versione sconosciuta viene rifiutata con unsupported_version, mai indovinata.

Primi passi

Prendi l'id di un modello da GET /v1/models e invia un primo messaggio.

curl
curl https://emtantares.com/api/developer/v1/messages \
  -H "x-api-key: $ANTARES_API_KEY" \
  -H "antares-version: 2026-09-24" \
  -H "content-type: application/json" \
  -d '{
    "model": "MODEL_ID",
    "max_tokens": 256,
    "messages": [{ "role": "user", "content": "Hello" }]
  }'
TypeScript
import Antares from "antares-sdk";

const client = new Antares(); // reads ANTARES_API_KEY
const message = await client.messages.create({
  model: "MODEL_ID",
  max_tokens: 256,
  messages: [{ role: "user", content: "Hello" }],
});
console.log(message.content, message.billing?.charged_micros);
Python
from antares import Antares

client = Antares()  # reads ANTARES_API_KEY
message = client.messages.create(
    model="MODEL_ID",
    max_tokens=256,
    messages=[{"role": "user", "content": "Hello"}],
)
print(message["content"], message["billing"]["charged_micros"])
Risposta
{
  "id": "msg_…",
  "type": "message",
  "role": "assistant",
  "model": "MODEL_ID",
  "content": [{ "type": "text", "text": "Hello! How can I help?" }],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": { "input_tokens": 9, "output_tokens": 8, "cache_read_input_tokens": 0, "cache_creation_input_tokens": 0 },
  "billing": { "currency": "EUR", "charged_micros": "41" }
}

Messages

POST /v1/messages genera il turno successivo dell'assistente in una conversazione. messages alterna turni user e assistant e inizia con un turno dell'utente; il content di ogni turno è una stringa o un elenco di blocchi (text, image, tool_use, tool_result).

CampoSignificato
modelL'id di un modello da /v1/models. Non c'è ripiego: non viene mai usato un altro modello al suo posto.
max_tokensIl massimo di token in uscita che il modello può produrre (obbligatorio). L'importo trattenuto si calcola con questo valore.
systemIstruzioni per tutta la conversazione: una stringa o un elenco di blocchi di testo.
temperature, top_pCampionamento, temperature da 0 a 1.
stop_sequencesFino a 4 stringhe che terminano la risposta.
tools, tool_choiceStrumenti che il modello può chiamare (vedi Strumenti).
metadata.user_idUn identificativo opaco del tuo utente finale, per le segnalazioni di abuso. Mai un indirizzo e-mail o un nome.
streamtrue per ricevere server-sent events (vedi Streaming).

La risposta è un message con blocchi di content, uno stop_reason (end_turn, max_tokens, tool_use o content_filter; una sequenza di stop riconosciuta chiude il messaggio con end_turn), l'usage in token e billing.charged_micros, l'addebito esatto. I campi sconosciuti vengono rifiutati con invalid_request, così un errore di battitura non passa mai inosservato.

Streaming

Con stream: true la risposta arriva come server-sent events. Il testo arriva negli eventi content_block_delta; una chiamata a uno strumento arriva intera, dopo il testo. message_delta porta il motivo di arresto finale, l'utilizzo e l'addebito, e message_stop chiude lo stream. Un evento ping ogni 15 secondi tiene aperte le connessioni inattive.

Eventi
event: message_start
data: {"type":"message_start","message":{"id":"msg_…","type":"message","role":"assistant","content":[],"stop_reason":null,…}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{…},"billing":{"currency":"EUR","charged_micros":"41"}}

event: message_stop
data: {"type":"message_stop"}

L'importo trattenuto, i controlli di spesa e la verifica dell'input avvengono prima che lo stream inizi, quindi un rifiuto in quella fase è un normale errore HTTP. Dopo l'inizio dello stream, un errore arriva come un ultimo evento error con il consueto oggetto di errore. La verifica dell'output avviene quando il modello ha finito: il testo già inviato non può essere ritirato, un output rifiutato chiude lo stream con content_blocked e l'utilizzo viene addebitato.

Lo streaming è offerto solo quando è abilitato per l'API: allora il modello elenca streaming tra le sue capabilities; altrimenti una richiesta in streaming viene rifiutata con streaming_unavailable.

TypeScript
const stream = client.messages.stream({
  model: "MODEL_ID", max_tokens: 512, messages: [{ role: "user", content: "Tell me a story" }],
});
for await (const text of stream.textStream()) process.stdout.write(text);
const final = await stream.finalMessage();

Strumenti

Descrivi ogni strumento con name, description e un input_schema (uno JSON Schema di un oggetto, fino a 64 KB; fino a 64 strumenti). Quando il modello decide di chiamarne uno, la risposta si ferma con tool_use e contiene un blocco tool_use. Esegui tu lo strumento e rimanda il risultato in un blocco tool_result del turno utente successivo, con lo stesso id.

tool_choice è auto (decide il modello), any (deve chiamare uno strumento), none, oppure { "type": "tool", "name": … } per uno strumento preciso. Un modello che non supporta gli strumenti rifiuta la richiesta con model_capability_unavailable.

Richiesta
{
  "model": "MODEL_ID",
  "max_tokens": 512,
  "tools": [{
    "name": "get_weather",
    "description": "Current weather for a city.",
    "input_schema": { "type": "object", "properties": { "city": { "type": "string" } }, "required": ["city"] }
  }],
  "messages": [
    { "role": "user", "content": "What is the weather in Rome?" },
    { "role": "assistant", "content": [{ "type": "tool_use", "id": "call_1", "name": "get_weather", "input": { "city": "Rome" } }] },
    { "role": "user", "content": [{ "type": "tool_result", "tool_use_id": "call_1", "content": "21 °C and sunny" }] }
  ]
}

Immagini

I turni dell'utente possono includere immagini come blocchi image in base64: JPEG, PNG, GIF (non animate) o WebP, al massimo 5 MB ciascuna, 20 per richiesta e 24 MB in tutto. Il media_type dichiarato deve corrispondere ai byte. L'API non scarica mai un URL per conto tuo. Ogni immagine viene trattenuta come al massimo 6.000 token di input, secondo le sue dimensioni.

Contenuto
{
  "role": "user",
  "content": [
    { "type": "image", "source": { "type": "base64", "media_type": "image/png", "data": "iVBORw0KGgo…" } },
    { "type": "text", "text": "What is in this picture?" }
  ]
}

Conteggio dei token

POST /v1/messages/count_tokens riceve lo stesso prompt (modello, system, messaggi, strumenti) e restituisce una stima dei suoi token di input, più reservation_input_tokens: il limite prudente con cui una chiamata reale con quel prompt viene trattenuta e limitata. È gratuito e non esegue il modello.

curl
curl https://emtantares.com/api/developer/v1/messages/count_tokens \
  -H "x-api-key: $ANTARES_API_KEY" -H "content-type: application/json" \
  -d '{ "model": "MODEL_ID", "messages": [{ "role": "user", "content": "Hello" }] }'

{ "input_tokens": 5, "reservation_input_tokens": 2311 }

Modelli e prezzi

GET /v1/models elenca i modelli disponibili ora, ordinati per id, in pagine fino a 100 (limit, after_id, before_id). Ogni modello riporta finestra di contesto, limite di output, capacità, il fornitore che lo serve (owned_by), una notice quando la sua origine va dichiarata e i prezzi in micro-euro per milione di token, addebitati dal tuo credito (l'IVA si paga quando acquisti il credito, come indicato al pagamento). I prezzi hanno una revisione e una data di scadenza; si applica il prezzo in vigore al momento della richiesta.

Nessun modello è ancora disponibile tramite l'API.

Errori

Ogni errore ha lo stesso corpo. error.type è la classe generale e segue lo stato HTTP; error.code è il motivo preciso e stabile su cui basare il codice; error.message è una frase fissa in inglese che non ripete mai il tuo input. Indica request_id (anche nell'intestazione request-id) all'assistenza.

402
{
  "type": "error",
  "error": {
    "type": "billing_error",
    "code": "API_INSUFFICIENT_FUNDS",
    "message": "The prepaid balance does not cover this request's maximum charge. Add funds in the console.",
    "request_id": "5f0c2c1e-…"
  },
  "request_id": "5f0c2c1e-…"
}
StatoTipoEsempi di codice
400invalid_request_errorinvalid_request, unsupported_version, context_limit_exceeded, model_capability_unavailable, streaming_unavailable
401authentication_errorinvalid_api_key
402billing_errorAPI_INSUFFICIENT_FUNDS, API_PROJECT_CAP_REACHED, API_PROJECT_MONTHLY_CAP_REACHED
403permission_errorinsufficient_scope, server_side_only, API_WALLET_FROZEN
404not_found_errormodel_unavailable, API_REQUEST_NOT_FOUND
409invalid_request_errorrequest_already_recorded, API_IDEMPOTENCY_CONFLICT
413request_too_largerequest_too_large
422invalid_request_errorcontent_blocked
429rate_limit_errorrate_limit_exceeded (con retry-after)
502, 503api_errorresponse_not_deliverable, usage_not_verified, safety_unavailable, service_unavailable

Riprova un 429 dopo retry-after e un 5xx con un'attesa crescente, sempre con la stessa Idempotency-Key. Non ripetere invariati gli altri errori 4xx.

Limiti di utilizzo e livelli

I limiti valgono per ogni chiave API, al minuto: richieste, token di input (contati con il limite prudente della richiesta quando viene ammessa) e token di output (contati man mano che vengono prodotti). Ogni risposta riporta antares-ratelimit-tier e, per ogni contatore, antares-ratelimit-<contatore>-limit, -remaining e -reset. Una richiesta oltre un limite riceve HTTP 429 con retry-after.

Il livello segue il credito che hai acquistato, al netto dei rimborsi. Il credito di prova usa sempre i limiti del livello 1.

LivelloDa credito acquistatoRichieste al minutoToken di input al minutoToken di output al minuto
0 tier_00,00 €1020.0004000
1 tier_110,00 €60100.00020.000
2 tier_250,00 €300400.00080.000
3 tier_3250,00 €10001.500.000300.000
4 tier_41000,00 €30004.000.000800.000

Idempotenza ed esito delle richieste

Invia una Idempotency-Key (da 8 a 128 caratteri tra A-Z a-z 0-9 . _ : -) con ogni richiesta a pagamento. Un nuovo tentativo con la stessa chiave e lo stesso corpo non viene mai eseguito né addebitato due volte: riceve 409 request_already_recorded. La stessa chiave con un corpo diverso riceve 409 API_IDEMPOTENCY_CONFLICT. Senza chiave, il server ne crea una e la restituisce nell'intestazione di risposta idempotency-key.

Dopo un timeout o una connessione persa, leggi cosa è successo con GET /v1/requests/{idempotency_key} invece di reinviare la richiesta: settled (addebitata), released (nessun addebito), reserved (ancora in corso) o uncertain (non è stato possibile confermare l'utilizzo presso il fornitore; l'importo trattenuto viene verificato e sbloccato entro 24 ore, salvo conferma dell'utilizzo). L'esito non contiene mai il contenuto.

curl
curl https://emtantares.com/api/developer/v1/messages -H "Idempotency-Key: order-1234" …

# later, after a timeout:
curl https://emtantares.com/api/developer/v1/requests/order-1234 -H "x-api-key: $ANTARES_API_KEY"
{ "id": "…", "status": "settled", "fundingMode": "live", "reservedMicros": "1200", "chargedMicros": "41", … }

Credito di prova

Gli account che ANTARES autorizza per i collaudi possono acquistare credito di prova con le carte di test di Stripe e spenderlo inviando antares-funding: test. Il credito di prova non si mescola mai con quello a pagamento, usa i limiti del livello 1 e un budget mensile fissato da ANTARES, e ogni risposta riporta "funding": "test". Per tutti gli altri account l'intestazione viene rifiutata.

Trattamento dei dati

  • L'API non conserva prompt, immagini né risposte. Per ogni richiesta a pagamento registra la chiave e il progetto, il modello, i conteggi dei token e l'id della richiesta presso il fornitore, gli importi trattenuti e addebitati, la Idempotency-Key e un'impronta SHA-256 del corpo della richiesta (per riconoscere i nuovi tentativi).
  • Per rispondere, il prompt viene inviato al fornitore che serve il modello (owned_by), secondo le condizioni di quel fornitore per il traffico API.
  • Prompt e risposte passano una verifica di sicurezza automatica prima e dopo l'esecuzione del modello, che può usare un servizio di moderazione di terze parti. Quando un contenuto viene rifiutato si registrano solo la sua impronta, le categorie e la lunghezza.
  • store non è supportato: negli endpoint di compatibilità si accetta solo false.
  • Con la piattaforma per sviluppatori si conserva ciò che scegli di conservare: i file caricati finché non li elimini, e le richieste di un batch finché ognuna non è stata eseguita, i suoi risultati per 29 giorni dopo la fine. File, batch e chiavi di amministrazione compaiono nell'esportazione dei dati dell'account e vengono cancellati con l'account.

Piattaforma per sviluppatori

Le sezioni che seguono descrivono la piattaforma per sviluppatori: file, documenti con citazioni, output strutturati, cache dei prompt, strumenti lato server e server MCP, batch di messaggi e API di amministrazione. Sono disponibili dove ANTARES le ha attivate; altrove le loro rotte rispondono 404 NOT_ENABLED e i campi vengono rifiutati come sconosciuti. Non cambiano nulla dei prezzi: ogni chiamata al modello è addebitata esattamente come una chiamata diretta a /v1/messages.

MetodoPercorsoChiave
POST, GET/v1/filesmessages:write (POST), any
GET, DELETE/v1/files/{file_id}any, messages:write (DELETE)
GET/v1/files/{file_id}/contentany
POST, GET/v1/messages/batchesmessages:write (POST), any
GET, DELETE/v1/messages/batches/{batch_id}any, messages:write (DELETE)
POST/v1/messages/batches/{batch_id}/cancelmessages:write
GET/v1/messages/batches/{batch_id}/resultsany
GET/v1/organizations/meadmin
GET, POST/v1/organizations/workspacesadmin
GET, POST/v1/organizations/workspaces/{workspace_id}admin
POST/v1/organizations/workspaces/{workspace_id}/archiveadmin
GET/v1/organizations/api_keysadmin
GET, POST/v1/organizations/api_keys/{api_key_id}admin
GET/v1/organizations/usage_report/messagesadmin
GET/v1/organizations/cost_reportadmin

File

POST /v1/files conserva un file (multipart, campo file, al massimo 32 MiB) per il progetto della chiave, così le richieste successive possono nominarlo invece di inviarlo di nuovo. Il tipo si legge dai byte: PDF, testo semplice, Markdown, CSV, JSON, DOCX, XLSX, PPTX, JPEG, PNG, GIF o WebP. Un progetto contiene al massimo 500 file e 512 MiB. GET /v1/files li elenca, GET /v1/files/{file_id} ne descrive uno, GET /v1/files/{file_id}/content lo scarica e DELETE lo elimina subito. I file sono gratuiti.

curl
curl https://emtantares.com/api/developer/v1/files \
  -H "x-api-key: $ANTARES_API_KEY" \
  -H "antares-version: 2026-09-24" \
  -F "file=@wing-loads.pdf"

Documenti e citazioni

Un turno dell'utente può contenere blocchi document: un PDF in base64, testo semplice, un elenco di blocchi di testo, o un file conservato ({ "type": "file", "file_id": … }; un PDF o un file Office si legge fino a 8 MiB). Anche un blocco immagine può nominare un'immagine conservata con file_id. Al massimo 20 documenti per richiesta.

Con citations.enabled il documento viene dato al modello in passaggi numerati e i blocchi text della risposta portano citations: il cited_text esatto con gli scostamenti char_location nel documento, oppure content_block_location per un documento dato a blocchi. Il testo che non cita nulla resta un blocco semplice. title dà il nome al documento; context è mostrato al modello ma mai citato.

Richiesta
{
  "model": "MODEL_ID",
  "max_tokens": 512,
  "messages": [{ "role": "user", "content": [
    { "type": "document", "source": { "type": "file", "file_id": "file_..." },
      "title": "Wing loads", "citations": { "enabled": true },
      "cache_control": { "type": "ephemeral" } },
    { "type": "text", "text": "Which load case sizes the spar?" }
  ] }]
}

Output strutturati

output_format: { "type": "json_schema", "schema": … } chiede un solo oggetto JSON conforme allo schema (un oggetto al primo livello, senza $ref, al massimo 64 KB). Al fornitore che serve il modello si chiede un output vincolato, quindi il modello deve elencare structured-output fra le sue capacità. Il messaggio porta allora parsed_output: l'oggetto, verificato di nuovo sullo schema, oppure null se la risposta non era conforme.

Richiesta
{
  "model": "MODEL_ID",
  "max_tokens": 256,
  "output_format": { "type": "json_schema", "schema": {
    "type": "object",
    "properties": { "part": { "type": "string" }, "mass_kg": { "type": "number" } },
    "required": ["part", "mass_kg"]
  } },
  "messages": [{ "role": "user", "content": "The bracket weighs 120 g." }]
}

Cache dei prompt

Metti cache_control: { "type": "ephemeral" } su un blocco di sistema, un blocco di testo, un documento o uno strumento per segnare dove finisce un prefisso riutilizzabile (al massimo 4 segni per richiesta). Dove il fornitore accetta segni espliciti, il prefisso resta in cache per circa cinque minuti; altrove la cache è automatica o assente. È disponibile solo la durata di cinque minuti: un ttl diverso da 5m è rifiutato con cache_ttl_unavailable. usage riporta cache_read_input_tokens e cache_creation_input_tokens, addebitati ai prezzi di cache del modello.

Strumenti lato server e server MCP

Gli strumenti lato server girano su ANTARES fra due chiamate al modello della stessa richiesta. web_search cerca con il servizio di ricerca di ANTARES ed è offerto solo finché quel servizio non costa nulla per ricerca; altrimenti è rifiutato con server_tool_unavailable. web_fetch legge una pagina https pubblica (mai un indirizzo privato, locale o di metadati). Entrambi accettano max_uses e allowed_domains o blocked_domains. L'esecuzione di codice e gli altri strumenti lato server non sono disponibili su questa API e sono rifiutati con server_tool_unavailable.

mcp_servers elenca fino a 5 server MCP remoti (https pubblico). ANTARES ne elenca gli strumenti, li offre al modello e li chiama quando lo chiede; authorization_token è usato solo per quella richiesta e mai conservato. La risposta mostra ciò che è stato eseguito come server_tool_use con web_search_tool_result o web_fetch_tool_result, e mcp_tool_use con mcp_tool_result.

Una richiesta così può richiedere più chiamate al modello, ognuna addebitata come una chiamata diretta con una propria chiave di idempotenza (la prima è la tua). billing.charged_micros è la loro somma e billing.model_calls il loro numero; usage.server_tool_use conta ricerche e letture di pagine. Dopo 8 chiamate il messaggio si ferma con pause_turn: rimandalo per continuare. Queste richieste non possono essere trasmesse in streaming.

Richiesta
{
  "model": "MODEL_ID",
  "max_tokens": 1024,
  "tools": [
    { "type": "web_search_20250305", "name": "web_search", "max_uses": 3 },
    { "type": "web_fetch_20250910", "name": "web_fetch", "allowed_domains": ["example.com"] }
  ],
  "mcp_servers": [{ "type": "url", "url": "https://mcp.example.com/mcp", "name": "inventory",
    "authorization_token": "YOUR_TOKEN" }],
  "messages": [{ "role": "user", "content": "Check the stock of part 42." }]
}

Batch di messaggi

POST /v1/messages/batches accetta fino a 1.000 richieste, ognuna con un custom_id e i params di una chiamata a /v1/messages (senza streaming). Vengono verificate subito ed eseguite in background entro 24 ore. Ognuna è una normale chiamata a pagamento registrata con la chiave di idempotenza batch_<batch>_<posizione>, quindi il suo esito si legge anche con /v1/requests/{idempotency_key}; non esiste un prezzo separato per i batch. Revocare la chiave che ha creato un batch ferma le richieste rimaste.

Leggi lo stato con GET /v1/messages/batches/{batch_id} (in_progress, canceling, ended, con i conteggi per esito), annulla con POST …/cancel e, quando è terminato, leggi GET …/results: una riga JSON per richiesta, in ordine, succeeded con il messaggio oppure errored, canceled o expired. I risultati restano 29 giorni, o finché non elimini il batch.

curl
curl https://emtantares.com/api/developer/v1/messages/batches \
  -H "x-api-key: $ANTARES_API_KEY" \
  -H "antares-version: 2026-09-24" \
  -H "content-type: application/json" \
  -d '{ "requests": [
    { "custom_id": "a", "params": { "model": "MODEL_ID", "max_tokens": 128,
      "messages": [{ "role": "user", "content": "Summarise report A." }] } }
  ] }'

API di amministrazione

Una chiave di amministrazione (ant_admin_v1_…, creata nella console in Chiavi di amministrazione e mostrata una sola volta) funziona solo su /v1/organizations/…: elenca, crea, rinomina e archivia gli spazi di lavoro (i progetti della console), elenca le chiavi API e le rinomina o le disattiva, e legge i rapporti. Non può mai chiamare un modello, e lì una chiave API è rifiutata con admin_key_required.

GET /v1/organizations/usage_report/messages restituisce richieste e token per giorno UTC (bucket_width=1d, fino a 31 giorni) o per ora (1h, fino a 2 giorni), raggruppati per model, workspace_id o api_key_id. GET /v1/organizations/cost_report restituisce gli addebiti già registrati per le richieste concluse, e quanto è ancora trattenuto, in micro-euro. Nessuno dei due calcola un prezzo: sommano ciò che è stato addebitato a ogni richiesta.

curl
curl "https://emtantares.com/api/developer/v1/organizations/usage_report/messages?starting_at=2026-10-01T00:00:00Z&group_by[]=model" \
  -H "x-api-key: $ANTARES_ADMIN_KEY" \
  -H "antares-version: 2026-09-24"

Strumenti per computer e browser

Aggiungi a tools { "type": "computer_v1", "name": "computer", "display_width_px": 1280, "display_height_px": 800 } oppure { "type": "browser_v1", "name": "browser" }. Sono strumenti del client: il modello chiede un'azione alla volta (screenshot, click, type, key, scroll… o, per il browser, navigate, read_page, find, click, type…) e il tuo driver la esegue su uno schermo o un browser che controlli tu. Rispondi con un tool_result; uno screenshot ci va dentro come blocco image (base64 o id di file). ANTARES non tocca mai la tua macchina.

Sicurezza: esegui il driver in una macchina virtuale o in un profilo del browser separato, senza i tuoi account, mostra alla persona che cosa sta per succedere, chiedi prima di qualsiasi azione irreversibile (inviare, comprare, cancellare) e tratta il testo delle pagine come dati: il modello riceve la stessa indicazione.

Strumento consulente

{ "type": "advisor_v1", "name": "advisor", "model": "…", "max_uses": 2 } permette al modello di consultare un secondo motore su un passaggio difficile. ANTARES manda a quel motore la conversazione fin lì e la domanda, e restituisce il consiglio come advisor_tool_result. Ogni consultazione è una normale chiamata a pagamento del motore consulente, contata in billing e in usage.server_tool_use.advisor_requests.

Skill

POST /v1/skills conserva una skill dal suo SKILL.md (frontmatter con name e description, poi le istruzioni) e fino a 20 file di testo; POST /v1/skills/{skill_id}/versions aggiunge una versione immutabile. Nomina le skill in una richiesta con skills: [{ "skill_id": "skill_…", "version": 2 }]: il modello vede nome e descrizione di ogni skill e ne legge istruzioni o file con lo strumento read_skill. Conservare e leggere le skill è gratuito.

Compattazione e messaggi di sistema

compaction: { "now": true } (oppure "trigger_input_tokens": 150000) riassume i turni prima degli ultimi keep_recent_messages (6 per impostazione predefinita) con una chiamata a pagamento al modello della richiesta, e risponde partendo dal riassunto. La risposta inizia con un blocco compaction: rimandalo come blocco utente al posto di quei turni. Un messaggio { "role": "system" } può comparire in qualsiasi punto di messages: vale da quel punto in poi. Gli strumenti possono cambiare fra un turno e l'altro.

Agenti ospitati

POST /v1/agents salva un agente (modello, prompt di sistema, strumenti, skill, max_tokens). POST /v1/sessions avvia una conversazione con lui, eventualmente con un archivio di memoria (POST /v1/memory_stores). POST /v1/sessions/{session_id}/events con { "content": … } esegue un turno: è una richiesta a /v1/messages costruita dall'agente e dalla sessione, addebitata esattamente come tale con la tua Idempotency-Key, e un nuovo invio con la stessa chiave restituisce il turno registrato. Con un archivio di memoria l'agente riceve lo strumento memory (leggere, scrivere, cancellare) e le voci restano per le sessioni successive.

Squadre: dai a un agente subagents (altri agenti dello stesso progetto, con una descrizione). I suoi turni offrono allora lo strumento server delegate (un compito a un sotto-agente) e run_workflow (un piano di fino a 8 compiti, con depends_on, eseguiti in parallelo quando possibile); ogni risposta di un sotto-agente è una normale chiamata a pagamento del modello di quell'agente. POST /v1/sessions/{session_id}/grades con { "model": …, "rubric": [{ "criterion": …, "weight": 1 }] } valuta la trascrizione (da 0 a 10 per criterio, media pesata) con una chiamata a pagamento. POST /v1/agents/{agent_id}/deployments con un schedule giornaliero o settimanale (ora e fuso orario) e un content apre una nuova sessione a ogni orario ed esegue quel primo turno con la tua chiave.

Esportazione OpenTelemetry

Con una chiave di amministrazione, PUT /v1/organizations/workspaces/{workspace_id}/otel_export con { "endpoint": "https://…/v1/traces", "headers": { … } } manda al tuo collector OpenTelemetry ogni richiesta conclusa dello spazio di lavoro come span OTLP/HTTP JSON: modello, token, stato e addebito già registrato, mai il testo del prompt o della risposta. Le intestazioni restano sigillate e non vengono mai restituite. Gli span partono pochi minuti dopo la richiesta.

Webhook dell'organizzazione

Con una chiave di amministrazione, POST /v1/organizations/webhooks con { "url": "https://…", "events": ["message_batch.ended"] } iscrive un indirizzo https agli eventi dell'organizzazione: message_batch.ended, workspace.created, workspace.archived, api_key.deactivated, session.turn_completed, skill.version_created. Il segreto di firma viene restituito una sola volta. Ogni consegna è un evento JSON (id, type, created_at, organization_id, data) firmato in antares-webhook-signature: t=<secondi>,v1=<HMAC-SHA256 esadecimale di "<t>.<corpo>">; verificala e rifiuta ciò che ha più di cinque minuti. Rispondi 2xx entro 10 secondi; altrimenti ANTARES riprova dopo 1, 5 e 30 minuti, poi 2, 6, 12 e 24 ore. POST …/test invia subito un evento webhook.test e GET …/deliveries mostra gli ultimi tentativi.

Esecuzione degli strumenti negli SDK

Gli SDK eseguono per te il ciclo degli strumenti: dai a ogni strumento una funzione run e client.beta.messages.toolRunner(...) (Python: client.beta.messages.tool_runner(...)) invia la richiesta, esegue gli strumenti che il modello chiede, rimanda i risultati e si ferma quando il modello risponde senza chiamare strumenti (al massimo 10 turni per impostazione predefinita). Ogni turno è una chiamata a pagamento con una propria chiave di idempotenza; un'eccezione in uno strumento viene rimandata come risultato di errore.

TypeScript
const { message } = await client.beta.messages.toolRunner({
  model: "MODEL_ID",
  max_tokens: 512,
  messages: [{ role: "user", content: "What is 12 x 7?" }],
  tools: [{
    name: "multiply",
    input_schema: { type: "object", properties: { a: { type: "number" }, b: { type: "number" } } },
    run: ({ a, b }) => String(Number(a) * Number(b)),
  }],
});

Endpoint di compatibilità

POST /v1/chat/completions accetta la forma di richiesta Chat Completions inviata da molti SDK e strumenti esistenti, sullo stesso percorso prepagato: imposta come URL di base del client quello qui sotto e la chiave API come sua chiave. Si accetta solo ciò che ANTARES può rispettare: una sola scelta, immagini data: in linea, temperature fino a 1. Senza max_tokens l'importo trattenuto usa fino a 4.096 token di output. Gli errori di questo percorso usano il corpo { "error": { "message", "type", "param", "code" } }.

Python
import os
from openai import OpenAI  # or any client that lets you set the base URL

client = OpenAI(base_url="https://emtantares.com/api/developer/v1", api_key=os.environ["ANTARES_API_KEY"])
reply = client.chat.completions.create(model="MODEL_ID", max_tokens=256,
                                       messages=[{"role": "user", "content": "Hello"}])

POST /v1/responses è il primo endpoint, solo testo, di questa API, mantenuto per chi lo usa già. Le nuove integrazioni usano /v1/messages.

Versioni e modifiche

La versione attuale è 2026-09-24. Le aggiunte che non possono rompere un client corretto (un nuovo endpoint, un nuovo campo facoltativo, un nuovo codice di errore o evento) possono arrivare all'interno di una versione; tutto il resto riceve una nuova versione, annunciata in anticipo, e quella precedente continua a rispondere ai client che la fissano.

  • 2026-09-24: Messages con strumenti, immagini e streaming; conteggio dei token; dettagli e pagine dei modelli; livelli con intestazioni dei limiti; errori tipizzati; x-api-key; Idempotency-Key facoltativa ed esito delle richieste; compatibilità Chat Completions.