EN ▾
stableaudio.top

Uncensored text API for your audio pipeline

Get API key

LangChain and LangGraph Without an API Key

You cannot run a hosted model with no key at all, but you can run LangChain and LangGraph without paying first. A one-click trial key and a changed base URL are enough.

Isometric node graph with glowing connected cubes representing a LangGraph agent workflow

Updated

Key points

  1. Every hosted endpoint needs a key; the trial key needs no card and is claimed with one click.

  2. LangChain's ChatOpenAI class works once you set base_url and model to uncensored.

  3. LangGraph agents with tool calling run unchanged, but fan-out branches must respect the concurrency limit.

  4. A typical six-call agent run costs about $0.0039, so the $0.50 trial covers roughly 128 such runs.

What "without an API key" can realistically mean

Searching for langchain and langraph without api key usually means one of three things. You may want to avoid paying before you know the stack works. You may not want to hand a credit card to yet another vendor. Or you may hope to run an agent graph with no credentials whatsoever.

The third wish cannot be met by any hosted service: a server that does the work for you has to know who is calling it. What you can get is a key that costs nothing and asks for no card. New users on this site can claim $0.50 of trial credit with one click on the API key page after signing up with Google or with an email and password. It is one per person and valid for 7 days.

The other route to "no key" is a local model served by something on your own machine. That works, but you carry the hardware, and a laptop will not match a hosted endpoint for long agent runs. A hosted trial is the faster way to find out whether your graph logic is sound, and the code you write is identical to what you will run later with a funded key.

Because the endpoint is OpenAI-compatible, LangChain does not need a special integration. You point its OpenAI chat class at a different base URL, give it the key, and name the model uncensored. Everything below assumes that setup.

Step 1: get the trial key and set the environment

Sign up, open the key page, and press the trial button. Copy the key and keep it out of your repository. Put it in an environment variable so the same script works with a trial key today and a full key later.

export UNCENSORED_API_KEY="paste-your-key-here"
pip install -U langchain-openai langgraph langchain-core

Before involving any framework, check the key with a plain request. Two minutes here saves an hour of reading stack traces that are really authentication errors.

curl https://api.stableaudio.top/v1/chat/completions \
  -H "Authorization: Bearer $UNCENSORED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"uncensored","messages":[{"role":"user","content":"Reply with one word: ready"}]}'

A GET /v1/models call is the other quick check; it should list uncensored. The trial key allows 2 concurrent requests and 60 requests per minute, which is plenty for developing a graph but worth remembering when you add parallel nodes.

Step 2: point LangChain at the endpoint

The class to use is ChatOpenAI from langchain-openai. Two arguments do the work: base_url and api_key. The model name is uncensored, and the usual sampling settings are passed through.

import os
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="uncensored",
    base_url="https://api.stableaudio.top/v1",
    api_key=os.environ["UNCENSORED_API_KEY"],
    temperature=0.7,
    max_retries=3,
)

print(llm.invoke("Give me three titles for an ambient track about rain.").content)

If this prints text, the connection is good. Streaming works the same way: iterate over llm.stream(...) and the chunks arrive over server-sent events, with usage reported at the end of the stream.

One common slip is leaving the OPENAI_API_KEY variable set from an old project. LangChain will happily send that value to your custom base URL if you forget to pass api_key. Pass the key explicitly and you remove the guesswork.

Step 3: a minimal LangGraph graph

LangGraph models your agent as state moving between nodes. The smallest useful graph has one node that calls the model and appends the reply to a message list. MessagesState gives you that list for free.

from langgraph.graph import StateGraph, MessagesState, START, END

def call_model(state: MessagesState):
    reply = llm.invoke(state["messages"])
    return {"messages": [reply]}

builder = StateGraph(MessagesState)
builder.add_node("model", call_model)
builder.add_edge(START, "model")
builder.add_edge("model", END)
graph = builder.compile()

out = graph.invoke({"messages": [("user", "Outline a three-act short story about a lighthouse keeper.")]})
print(out["messages"][-1].content)

This is deliberately plain. The point is that nothing in LangGraph knows or cares which provider sits behind llm. Any node can take a different model object, so you can later give a cheap planning step and a longer writing step their own settings, such as a lower temperature for planning.

Step 4: add tools and a loop

Agents get interesting when the model can call functions. The endpoint supports tool calling with tools and tool_choice, and tool results go back as role: "tool" messages. LangChain and LangGraph handle that plumbing for you.

from langchain_core.tools import tool
from langgraph.prebuilt import ToolNode, tools_condition

@tool
def word_count(text: str) -> int:
    'Count the words in a piece of text.'
    return len(text.split())

tools = [word_count]
llm_with_tools = llm.bind_tools(tools)

def agent(state: MessagesState):
    return {"messages": [llm_with_tools.invoke(state["messages"])]}

builder = StateGraph(MessagesState)
builder.add_node("agent", agent)
builder.add_node("tools", ToolNode(tools))
builder.add_edge(START, "agent")
builder.add_conditional_edges("agent", tools_condition)
builder.add_edge("tools", "agent")
graph = builder.compile()

result = graph.invoke({"messages": [("user", "Write a 40-word product blurb, then check its word count with the tool.")]})
print(result["messages"][-1].content)

The loop is the whole idea: the agent node answers, tools_condition checks whether the reply asked for a tool, the tool node runs it, and control returns to the agent. When a reply has no tool call, the graph ends.

Open-weight models vary in how tidy their tool arguments are. If a call comes back malformed, tighten the tool's docstring, lower the temperature, and keep the argument schema small. Short, typed schemas fail less often than long ones with many optional fields.

Rate limits, retries and parallel branches

The place agent graphs most often trip is concurrency. A full key allows 8 concurrent requests and 300 requests per minute; a trial key allows 2 and 60. If your graph fans out into five parallel nodes on a trial key, three of them will be rejected with HTTP 429 and the error code concurrency. Going over the per-minute budget returns rate_limited. Temporary overload also gives a 429, with a Retry-After: 5 header.

Three habits keep this manageable:

  • Keep max_retries at 2 or 3 on ChatOpenAI so short 429s are retried with backoff.
  • Cap fan-out at your concurrency limit. In LangGraph you can pass config={"max_concurrency": 2} when invoking the graph.
  • Remember that a streamed request holds its slot until the stream ends, so a slow consumer keeps a slot busy.
out = graph.invoke(
    {"messages": [("user", "Draft five taglines in parallel.")]},
    config={"max_concurrency": 2},
)

The response headers help with debugging. X-Request-Id identifies a call if you need to ask support about it, and X-Balance-USD shows your remaining credit after each request.

Debugging checklist when the graph misbehaves

Most failures in a first LangGraph project are not about the model. They come from configuration, and a short checklist catches nearly all of them.

  1. 401 or authentication errors. The key is missing, mistyped, or an old OPENAI_API_KEY is being read instead. Print the first four characters of the value your script actually uses.
  2. 404 or model not found. The model name must be uncensored. Call GET /v1/models if you are unsure what the endpoint lists.
  3. Connection errors. The base URL must end in /v1 and must not include /chat/completions; the client adds that part.
  4. Endless loops. If the agent keeps calling a tool, the tool's return value may not answer the question. Return plain, short strings and set a recursion limit through the graph config so a bad loop stops early.
  5. Empty or odd replies. Print the full message list after a run. Often an earlier node wrote a system message that contradicts the later one.

When a request fails on the server side, quote the X-Request-Id header in your message to support. It lets them find that exact call without guesswork. Keep in mind too that failed or refused requests are not charged, so a debugging session full of errors does not eat your trial credit.

One more design point. Give each node a narrow job and a short prompt. A graph with a planner, a writer and a checker, each with its own small system message, is easier to test than a single node with a page of instructions, and each piece can be tried alone with a direct llm.invoke call before you wire it in.

What a trial run actually costs

Pricing is $0.15 per 1M input tokens and $0.50 per 1M output tokens, from prepaid credit. Failed or refused requests are not charged. Agent graphs call the model several times per task, and every call resends the growing message list, so input tokens dominate.

Take a run with six model calls. Say each call sends 3,000 tokens in and returns 400 tokens out. That is 18,000 input tokens and 2,400 output tokens.

  • Input: 18,000 / 1,000,000 x $0.15 = $0.0027
  • Output: 2,400 / 1,000,000 x $0.50 = $0.0012
  • Total: $0.0039 per run

The $0.50 trial divided by $0.0039 is about 128 runs of that size, enough to build and test a graph properly. When you outgrow it, top-ups run from $20 to $500 in whole amounts, with a bonus of 5% from $50, 10% from $100 and 15% from $200; the pricing page has the details. You can pay by card (Visa, Mastercard, Apple Pay, Google Pay) or with crypto (USDT on TRC20, USDC on Base). Credit never expires, and prompts are not used for training.

The context window is 100,000 tokens for prompt plus completion, so long agent histories fit, but you pay for every token you resend. Trimming old messages with LangGraph's message utilities keeps cost and latency down. For the raw request format behind all of this, see the API docs.

Questions and answers

Can I use LangChain or LangGraph with no API key at all?

Not with a hosted model. The server must identify the caller. You can claim a free trial key with one click, no card needed, or run a local model yourself.

Which LangChain class should I use?

ChatOpenAI from langchain-openai. Set base_url to the endpoint, pass the key as api_key and use the model name uncensored.

Does tool calling work inside LangGraph agents?

Yes. The endpoint supports tools, tool_choice and role tool results, so bind_tools, ToolNode and tools_condition work as in the examples above.

Why do I get 429 errors when my graph runs branches in parallel?

You exceeded the concurrency limit, 2 on the trial key and 8 on a full key. Cap max_concurrency in the graph config and keep retries enabled.

Is the trial credit enough to test an agent?

Usually. At about $0.0039 for a six-call run of moderate size, $0.50 covers well over a hundred runs within the 7-day validity.

Your key is one form away

Create an account, copy the key, change the base URL. That is the whole setup.

Get API key