Quickstart
Run one agent, inspect the trace, and learn the basic loop for building with PromptRails.
Best for
New teams, product owners, and engineers evaluating the workflow
This guide takes you from an empty or early workspace to one useful agent run. The first milestone is not configuring every feature. It is creating one agent that can do a small task, running it once, and using the trace to understand what happened.
Prerequisites
- A PromptRails account
- A workspace you can edit
- A model credential, tool credential, or template that can power the first agent
- A small task you want the agent to complete
Step 1: Choose the entry point
Pick the fastest path to a real run:
- Use Build with assistant when you want PromptRails to help draft the agent.
- Use Browse templates when a starter workflow is close to your use case.
- Use Open Studio when you already know the agent, prompt, tool, or data source you want to configure.
The goal is not to build the final production workflow on the first pass. The goal is to get one inspectable run.
If you use the Assistant, keep the same review loop: accept it as a draft, run the agent, inspect the trace, then save a version only after the behavior is clear.
Step 2: Create or select an agent
Open Studio and create an agent from a template, with the assistant, or manually. Give it a clear job, such as "classify support tickets", "summarize an applicant profile", or "answer with retrieved context".
Before you run, confirm three things:
- The agent has a prompt or instruction it can use.
- The required model, data source, or tool credential is connected.
- The input field is understandable to the person or system that will call it.
Step 3: Connect access
Add the access the agent needs to do the first job. This might be an LLM credential, an MCP tool, a data source, a Slack or Teams connection, or an approval step.
Keep this first version narrow. One useful tool or one useful data source is better than a broad configuration you cannot debug.
Step 4: Run the agent
Run the agent from the product, from a connected channel, from an app integration, or from code. Use an input that represents a real task, not a toy prompt.
If you are integrating from your own application, create an API key in Settings > API Keys and keep the SDK setup in a small local script until the run behaves correctly.
Technical detailsApplication integration with SDKs
Install the PromptRails SDK for your language of choice.
Python
pip install promptrailsJavaScript / TypeScript
npm install @promptrails/sdkGo
go get github.com/promptrails/go-sdkCreate an API key with agents:execute, executions:read, and traces:read scopes for this local test. You can find the agent ID in Studio by opening the agent and copying it from the detail view or API examples.
Execute an agent
Python
from promptrails import PromptRails
client = PromptRails(api_key="your-api-key-here")
# Execute an agent
result = client.agents.execute(
agent_id="your-agent-id",
input={
"message": "What is the capital of France?"
}
)
print(result["data"]["output"])Python (async)
import asyncio
from promptrails import AsyncPromptRails
async def main():
client = AsyncPromptRails(api_key="your-api-key-here")
result = await client.agents.execute(
agent_id="your-agent-id",
input={
"message": "What is the capital of France?"
}
)
print(result["data"]["output"])
await client.close()
asyncio.run(main())JavaScript / TypeScript
import { PromptRails } from '@promptrails/sdk'
const client = new PromptRails({
apiKey: 'your-api-key-here',
})
const result = await client.agents.execute('your-agent-id', {
input: {
message: 'What is the capital of France?',
},
})
console.log(result.data.output)Go
package main
import (
"context"
"fmt"
"log"
promptrails "github.com/promptrails/go-sdk"
)
func main() {
client := promptrails.NewClient("your-api-key-here")
ctx := context.Background()
result, err := client.Agents.Execute(ctx, "your-agent-id", &promptrails.ExecuteAgentParams{
Input: map[string]any{"message": "What is the capital of France?"},
Sync: true,
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Data.Output)
}List recent executions
Python
# List recent executions
executions = client.executions.list(page=1, limit=10)
for execution in executions["data"]:
print(f"ID: {execution['id']}")
print(f"Status: {execution['status']}")
print(f"Cost: ${execution['cost']:.6f}")
print(f"Duration: {execution['duration_ms']}ms")
print("---")JavaScript / TypeScript
const executions = await client.executions.list({ page: 1, limit: 10 })
for (const execution of executions.data) {
console.log(`ID: ${execution.id}`)
console.log(`Status: ${execution.status}`)
console.log(`Cost: $${execution.cost.toFixed(6)}`)
console.log(`Duration: ${execution.duration_ms}ms`)
console.log('---')
}Go
executions, err := client.Executions.List(ctx, &promptrails.ListExecutionsParams{
Page: 1,
Limit: 10,
})
if err != nil {
log.Fatal(err)
}
for _, exec := range executions.Data {
fmt.Printf("ID: %s\n", exec.ID)
fmt.Printf("Status: %s\n", exec.Status)
fmt.Println("---")
}Step 5: Open the trace
Every execution creates a trace. Open it after the first run and answer practical questions: which prompt rendered, which model was called, whether a tool or data source ran, how long each step took, what it cost, and where any error happened.
Technical detailsTrace lookup with SDKs
Python
# Get traces for a specific execution
traces = client.traces.list(execution_id="your-execution-id")
for span in traces["data"]:
print(f"Span: {span['name']} ({span['kind']})")
print(f"Status: {span['status']}")
print(f"Duration: {span['duration_ms']}ms")
if span.get("cost"):
print(f"Cost: ${span['cost']:.6f}")
print("---")JavaScript / TypeScript
const traces = await client.traces.list({
executionId: 'your-execution-id',
})
for (const span of traces.data) {
console.log(`Span: ${span.name} (${span.kind})`)
console.log(`Status: ${span.status}`)
console.log(`Duration: ${span.duration_ms}ms`)
if (span.cost) {
console.log(`Cost: $${span.cost.toFixed(6)}`)
}
console.log('---')
}Go
traces, err := client.Traces.List(ctx, &promptrails.ListTracesParams{
ExecutionID: "your-execution-id",
})
if err != nil {
log.Fatal(err)
}
for _, span := range traces.Data {
fmt.Printf("Span: %s (%s)\n", span.Name, span.Kind)
fmt.Printf("Status: %s\n", span.Status)
fmt.Println("---")
}Step 6: Decide the next action
Once the trace is readable, choose the next improvement:
- If the output is wrong, update the prompt or the tool/data connection.
- If the flow needs a human checkpoint, add an approval.
- If quality needs to be measured over time, turn the run into an evaluation case.
- If the agent belongs in a chat experience, connect it to an app or use chat sessions from your application.
Technical detailsChat session SDK examples
Python
# Create a chat session
session = client.chat.create_session(agent_id="your-agent-id")
# Send messages
response = client.chat.send_message(
session.id,
content="Hello, tell me about machine learning."
)
print(response.content)
# Continue the conversation
response = client.chat.send_message(
session.id,
content="Can you give me a specific example?"
)
print(response.content)JavaScript / TypeScript
// Create a chat session
const session = await client.chat.createSession({
agentId: 'your-agent-id',
})
// Send messages
const response = await client.chat.sendMessage(session.id, {
content: 'Hello, tell me about machine learning.',
})
console.log(response.content)
// Continue the conversation
const followUp = await client.chat.sendMessage(session.id, {
content: 'Can you give me a specific example?',
})
console.log(followUp.content)Next Steps
After the first run, the next useful docs are:
- Agents -- Choose the right agent shape for the workflow.
- Prompts -- Manage prompt text, models, schemas, and versions.
- MCP Tools -- Give agents access to external systems.
- Tracing -- Debug execution behavior in detail.
- Evaluations -- Turn important runs into repeatable quality checks.