AIPAKA API
Ask questions of the Pistoia Alliance knowledge base from your own systems. AIPAKA answers using Pistoia Alliance webinars, meetings, documents and website content, and returns the sources it used.
Requesting access
API access is not self-service. To use the API, contact your Pistoia Alliance representative or the Alliance team and tell them what you want to build. If approved, the Alliance creates a named access token for your system and sends it to you securely.
A token is issued to one organisation, for its own use only. It must not be shared with, passed to, or used on behalf of any other organisation, for any reason. If sharing is identified, the token will be revoked without notice. If another organisation needs access, it must request its own token from the Alliance.
Overview
Base URL: https://insight.pistoiaalliance.org
Each client system gets its own token. A token is tied to your system's name and:
- can call
POST /chatonly; - has an expiry date (usually one year);
- may have a monthly allowance of calls, agreed with the Alliance (it resets on the 1st of each month, UTC);
- is rate limited (30 requests per minute by default);
- can be revoked by the Alliance at any time.
Check that the service is running (no token needed):
curl https://insight.pistoiaalliance.org/health
Authentication
Send your token in either header:
Authorization: Bearer pa_s2s_your-system_xxxxxxxxxxxxxxxxxxxx
X-API-Key: pa_s2s_your-system_xxxxxxxxxxxxxxxxxxxx
Tokens in the URL are not accepted. Any authentication failure returns 401 with {"detail": "Authentication required."}, whatever the cause (missing, wrong, expired or revoked).
Your token belongs to your organisation alone. Sharing it with any other organisation, for any reason, breaches the terms of access and will result in the token being revoked.
POST/chat
Ask a question and receive an answer with the sources it was drawn from. Send JSON with Content-Type: application/json.
Request
| Field | Type | Description |
|---|---|---|
query | string, required | Your question, 1–2000 characters. |
session_id | string or null | Omit or null to start a new conversation. Pass the value from a previous response to ask a follow-up. |
top_k | integer | Number of source excerpts to retrieve, 1–20 (default 8). |
filters | object | Optional. speakers (list of names), date_from and date_to (ISO dates such as 2025-01-01), session (partial session name). |
Response
{
"answer": "The Pistoia Alliance's FAIR maturity work ...",
"sources": [
{
"session_name": "FAIR Maturity Matrix Introduction",
"session_date": "2025-03-04",
"speaker": "Jane Smith",
"timestamp": "00:12:40",
"text": "...the excerpt used to support the answer...",
"score": 0.0312,
"source_kind": "transcript",
"content_label": "Video",
"citation_url": "https://pistoiaalliance.org/resource-library/...",
"direct_citation_url": "https://vimeo.com/1008786712#t=760"
}
],
"query": "What has the Pistoia Alliance said about FAIR data maturity?",
"session_id": "5b1f2c0e-8a4e-4a52-9c1f-0e7a6a1d2b33"
}
| Field | Description |
|---|---|
answer | The generated answer, with light Markdown and inline citations such as [Session: … | Date: 2025-03-04 | Speaker: … | ~00:12:40] or [Document: … | Date: …]. |
sources | The excerpts the answer was based on. May be empty: questions about counts or lists of events are answered from a structured catalogue and carry no excerpts. |
session_id | Always returned. Pass it back to continue the conversation. |
sources[].content_label | Display label such as Video, Transcript, Document, Write-up, Page, Project, Event or FAQ. |
sources[].citation_url, direct_citation_url | Links to the item and to the underlying resource. Either may be null. Addresses starting with https:// are ordinary links (members-only pages still ask the reader to sign in). Addresses starting with / belong to the AIPAKA web app and only open for signed-in members. |
Conversations
- Pass the
session_idfrom one response into the next request to ask follow-ups in context. - The last 6 turns are remembered. A conversation is forgotten after 30 minutes of inactivity and whenever the service restarts, so be ready to start afresh.
- Keep one
session_idper end user; never share one between users.
Errors and limits
| Status | Meaning | What to do |
|---|---|---|
200 | Success | |
401 | Missing, invalid, expired or revoked token, or an endpoint other than POST /chat | Check the header and the token's expiry; contact the Alliance. |
422 | Invalid request body (empty or over-long query, top_k out of range) | Fix the request; do not retry unchanged. |
429 | Per-minute limit exceeded; includes Retry-After: 60 | Wait, then retry. Space requests out or ask for a higher limit. |
429 | {"detail": "Monthly allowance exceeded."} — you have used your agreed number of calls for this calendar month. Retry-After is the number of seconds until the allowance resets. | Do not retry before then: the allowance resets on the 1st of each month (UTC). Contact the Alliance if you need more. |
5xx | Temporary problem | Retry with backoff (2s, 4s, 8s), up to 3 times. |
Answers usually take a few seconds and can take longer for complex questions, so set your client timeout to at least 60 seconds. Each call uses a paid AI model: cache answers to repeated questions where sensible and avoid automated loops.
Examples
curl
curl -X POST https://insight.pistoiaalliance.org/chat \
-H "Authorization: Bearer $AIPAKA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query": "Which sessions covered the IDMP ontology?"}'
Python
import os, requests
BASE = "https://insight.pistoiaalliance.org"
HEADERS = {"Authorization": f"Bearer {os.environ['AIPAKA_TOKEN']}"}
def ask(query, session_id=None):
r = requests.post(f"{BASE}/chat", headers=HEADERS,
json={"query": query, "session_id": session_id}, timeout=90)
r.raise_for_status()
return r.json()
first = ask("Which sessions covered the IDMP ontology?")
print(first["answer"])
follow_up = ask("Which of those were in 2024?", session_id=first["session_id"])
print(follow_up["answer"])
JavaScript (Node, server side)
const res = await fetch("https://insight.pistoiaalliance.org/chat", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.AIPAKA_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ query: "What were the main points on knowledge graphs?",
filters: { date_from: "2025-01-01", date_to: "2025-12-31" } }),
signal: AbortSignal.timeout(90_000),
});
if (!res.ok) throw new Error(`AIPAKA error ${res.status}`);
const { answer, sources, session_id } = await res.json();
Before you go live
- Token used by your organisation only and never shared with another organisation. Sharing leads to revocation.
- Token kept in a secrets manager or environment variable, not in code or a browser.
- Calls made from your server only.
- Client timeout of 60 seconds or more;
429and5xxhandled with retry and backoff. - Citations shown alongside answers, with a note that answers are AI-generated.
- Your users are entitled to see Pistoia Alliance members-only content.
- You know the token's expiry date and have a reminder to ask for a replacement.
For a new token, a higher rate limit, or to replace or revoke a token, contact the Alliance and quote your system name (the part of the token after pa_s2s_). Never send the token itself by email or chat.