Skip to content

Connect a LangGraph agent

Relay does not require LangGraph, but LangGraph works well behind the webhook contract. Relay delivers the user turn; your backend invokes the graph; your backend replies to Relay with one POST.

Terminal window
python3 -m venv .venv
source .venv/bin/activate
pip install fastapi uvicorn langgraph typing_extensions requests
import os
from typing_extensions import TypedDict
import requests
from fastapi import FastAPI, Request, Response
from langgraph.graph import END, START, StateGraph
RELAY_API_KEY = os.environ["RELAY_API_KEY"]
class State(TypedDict):
user_text: str
answer: str
def answer_user(state: State) -> dict:
return {
"answer": (
"Relay received your message and routed it through LangGraph: "
+ state["user_text"]
)
}
builder = StateGraph(State)
builder.add_node("answer_user", answer_user)
builder.add_edge(START, "answer_user")
builder.add_edge("answer_user", END)
graph = builder.compile()
app = FastAPI()
@app.post("/relay/webhook")
async def relay_webhook(request: Request):
event = await request.json()
if event["type"] != "message.received":
return Response(status_code=204)
conversation_id = event["conversation"]["id"]
user_text = event["message"]["fallback_text"]
result = graph.invoke({"user_text": user_text, "answer": ""})
answer = result["answer"]
relay_response = requests.post(
f"https://api.relay.app/v1/conversations/{conversation_id}/messages",
headers={
"Authorization": f"Bearer {RELAY_API_KEY}",
"Content-Type": "application/json",
"Idempotency-Key": f"langgraph-{event['id']}",
},
json={
"content": [{"type": "text", "text": answer}],
"fallbackText": answer,
},
timeout=10,
)
relay_response.raise_for_status()
return Response(status_code=204)
Terminal window
export RELAY_API_KEY="relay_live_your_api_key"
uvicorn app:app --host 0.0.0.0 --port 8787

Expose http://localhost:8787/relay/webhook with your tunnel of choice and paste the public HTTPS URL into the Relay dashboard.

Before using this in production, verify Relay-Signature over the raw request body. The webhooks reference includes copy-paste TypeScript and Python verification functions.

Use event["conversation"]["id"] as the stable LangGraph thread or checkpoint key. Relay sends that ID on every turn so the agent backend never has to infer which conversation to answer.