The Generative AI and GraphRAG workshops we provide on GraphAcademy challenge you to make calls to LLM from your own code. Up until recently, we have provided OpenAI keys as part of the workshop. Now, we have provided a
but you do not need an OpenAI key to run them. Requests go through the GraphAcademy AI proxy instead.
This page is a reference for learners, and for anyone (or any coding agent) working out why a request to the proxy failed.
The GraphAcademy LLM proxy
The proxy is an OpenAI-compatible API hosted on GraphAcademy. You can find it at the following URL:
https://graphacademy.neo4j.com/api/llm/v1It supports POST /chat/completions (including streaming) and POST /embeddings. Any OpenAI SDK, LangChain, Pydantic AI, or curl works. You change the base URL and the API key and nothing else.
Each key starts with ga- and belongs to one user on one course. On each request, the proxy checks the key, applies the course limits, then forwards the request:
| Model prefix | Forwarded to |
|---|---|
gpt-*, o1, o3 and similar | OpenAI |
text-embedding-* | OpenAI (embeddings) |
claude-* | Anthropic, chat only, when the course allows it |
Each course lists the models it allows. Anything else is rejected.
Get a key and configure your project
- Enrol on the workshop.
- Open the lesson with the Workshop AI access panel and accept the acceptable-use terms.
- Copy the API key from the panel into your
.envfile:
OPENAI_API_KEY="ga-..."
OPENAI_BASE_URL="https://graphacademy.neo4j.com/api/llm/v1"The keys have been tested on a number of popular frameworks, so you can switch this out for a real key when you are ready to deploy your code.
Limits
Each course sets its own limits. These are the values for the Agent Memory workshop:
| Limit | Value | Notes |
|---|---|---|
| Models | gpt-5.2, gpt-4o-mini, text-embedding-3-small | gpt-4o-mini is used by the memory extractor |
| Token budget | 1,000,000 | A lifetime total per enrolment, prompt plus completion. Not reset daily or per lesson |
| Rate limit | 120 calls every 2 minutes | Cached responses do not count |
| Access window | 7 days by default | Starts when the key is issued. Requesting a key again restarts it |
| Idle timeout | 30 minutes | Measured from the last time you loaded a lesson or called a GraphAcademy MCP tool |
| Output | 2,048 tokens maximum | Larger max_tokens values are clamped |
| Request size | 128 KB | |
| Choices | n must be 1 or omitted |
Two of these catch people out.
You must keep the lesson open. The proxy only serves a key whose owner has been active on the course in the last 30 minutes. Loading any lesson of the course counts. When the session goes idle, a "Still working?" prompt appears in the lesson. Click I'm still working and the same key starts working again.
Claude models have fewer features. Requests to claude-* models cannot use tools, tool_choice, functions, function_call, or response_format. Use an OpenAI model for tool calling and structured output.
Identical requests are cached for 15 minutes (chat) or 24 hours (embeddings). Streaming responses are never cached. A response with X-Proxy-Cache: HIT costs no tokens.
Common errors
Every error uses the OpenAI error shape:
{
"error": {
"message": "Your workshop AI session has gone idle. ...",
"type": "permission_error",
"code": "inactive"
}
}Match on code, which is stable, rather than on message.
| Status | code | Cause | Fix |
|---|---|---|---|
| 403 | inactive | No lesson activity in the last 30 minutes | Open any lesson of the course, or click I'm still working, then retry. The key is unchanged |
| 403 | access-expired | The access window has ended | Open the Workshop AI access panel and request a key again |
| 429 | throttled | Too many calls in the 2-minute window | Wait a minute and retry. Reduce parallel requests |
| 402 | budget-exhausted | The token budget is used | Ask your instructor for more. Cached calls would not have counted |
| 401 | unauthorized | The key is not valid | Copy the key from the panel again. Check you are using the key for this course and that the base URL ends /api/llm/v1 |
| 401 | missing-token | No Authorization header | Set OPENAI_API_KEY |
| 403 | not-enrolled | You are not enrolled | Enrol on the course, then retry |
| 403 | course-not-enabled | The course has no proxy access, or the key is for another course | Use the key from the course you are working on |
| 400 | model-not-allowed | The model is not on the course list | Use one of the models the panel shows |
| 400 | unsupported-for-model | Tools or structured output sent to a claude-* model | Use an OpenAI model |
| 400 | embeddings-non-openai | An embeddings request for a non-OpenAI model | Use text-embedding-3-small |
| 400 | invalid-request | The body failed validation, for example n greater than 1 | Read message and fix the parameter |
| 400 | invalid-json | The body is not valid JSON | Check nothing overrides the SDK request body |
| 413 | body-too-large | The body is over 128 KB | Shorten the prompt or messages |
| 503 | service-unavailable | Proxy access is not configured on the server | Not caused by your code. Tell your instructor |
Errors from the upstream provider are passed through with the provider's own status code. A 502 with upstream_error means the proxy could not reach the provider. Retry after a short wait.
Your key identifies you. Do not paste it into issues, chat, or a public repository.
If a request still fails
Work through this list in order. It follows the order the proxy checks each request, so the first item that fails is the cause.
OPENAI_API_KEYstarts withga-andOPENAI_BASE_URLends with/api/llm/v1.- You are enrolled on the course the key was issued for.
- The key has not passed its access window.
- You have loaded a lesson of the course in the last 30 minutes.
- The model is on the course's allowed list.
- You are under the call rate limit.
- You have tokens left in the budget.
If all of these hold and you still get an error, include the code and HTTP status when you ask for help.
Comments (0)
Loading comments...