Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/mastra-ai/mastra/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Handler functions process HTTP requests in custom API routes. They receive a Hono context object with request information and helper methods for crafting responses.

Handler Type

type Handler<Variables, Path, PathParams> = (
  c: Context<{ Variables: Variables }, Path, PathParams>
) => Response | Promise<Response>

Context Object

The context object provides access to the request, Mastra instance, and response helpers.

Properties

req
HonoRequest
The HTTP request object with methods for accessing headers, params, query, and body
env
object
Environment variables and runtime context

Context Variables (via c.get())

mastra
Mastra
The Mastra instance, accessible via c.get('mastra')
requestContext
RequestContext
Request context for dependency injection, accessible via c.get('requestContext')

Request Methods

req.param

c.req.param(name: string): string
c.req.param(): Record<string, string>
Gets URL path parameters.
// Route: /users/:id
const id = c.req.param('id');
// Or get all params
const params = c.req.param();

req.query

c.req.query(name: string): string | undefined
c.req.query(): Record<string, string>
Gets URL query parameters.
// URL: /search?q=hello&limit=10
const query = c.req.query('q'); // 'hello'
const limit = c.req.query('limit'); // '10'
// Or get all queries
const queries = c.req.query();

req.header

c.req.header(name: string): string | undefined
c.req.header(): Record<string, string>
Gets request headers.
const auth = c.req.header('authorization');
const contentType = c.req.header('content-type');
// Or get all headers
const headers = c.req.header();

req.json

c.req.json<T>(): Promise<T>
Parses request body as JSON.
const body = await c.req.json<{ name: string; email: string }>();
console.log(body.name, body.email);

req.text

c.req.text(): Promise<string>
Gets request body as text.
const text = await c.req.text();

req.formData

c.req.formData(): Promise<FormData>
Parses request body as FormData.
const formData = await c.req.formData();
const file = formData.get('file');

Response Methods

json

c.json<T>(object: T, status?: number, headers?: Record<string, string>): Response
Returns a JSON response.
return c.json({ message: 'Success', data: result }, 200);

return c.json({ error: 'Not found' }, 404);

return c.json({ data }, 200, {
  'X-Custom-Header': 'value'
});

text

c.text(text: string, status?: number, headers?: Record<string, string>): Response
Returns a plain text response.
return c.text('Hello, World!');

return c.text('Not Found', 404);

html

c.html(html: string, status?: number, headers?: Record<string, string>): Response
Returns an HTML response.
return c.html('<h1>Welcome</h1>');

redirect

c.redirect(url: string, status?: number): Response
Redirects to a URL.
return c.redirect('/login', 302);

return c.redirect('https://example.com', 301);

notFound

c.notFound(): Response
Returns a 404 Not Found response.
return c.notFound();

Context Methods

get

c.get<T>(key: string): T
Gets a context variable.
const mastra = c.get('mastra');
const requestContext = c.get('requestContext');

set

c.set<T>(key: string, value: T): void
Sets a context variable.
c.set('user', authenticatedUser);

var

c.var: Variables
Access to all context variables.
const { mastra, requestContext } = c.var;

Example Handlers

Basic Handler

import { registerApiRoute } from '@mastra/core';

registerApiRoute('/hello', {
  method: 'GET',
  handler: async (c) => {
    return c.json({ message: 'Hello, World!' });
  }
});

Path Parameters

registerApiRoute('/users/:id', {
  method: 'GET',
  handler: async (c) => {
    const id = c.req.param('id');
    const mastra = c.get('mastra');
    const storage = mastra.getStorage();
    
    // Fetch user from storage
    const user = await storage.getUser(id);
    
    if (!user) {
      return c.json({ error: 'User not found' }, 404);
    }
    
    return c.json({ user });
  }
});

Query Parameters

registerApiRoute('/search', {
  method: 'GET',
  handler: async (c) => {
    const query = c.req.query('q');
    const limit = parseInt(c.req.query('limit') || '10');
    const offset = parseInt(c.req.query('offset') || '0');
    
    // Perform search
    const results = await searchDatabase(query, { limit, offset });
    
    return c.json({ query, results, limit, offset });
  }
});

POST with JSON Body

registerApiRoute('/users', {
  method: 'POST',
  handler: async (c) => {
    const body = await c.req.json<{
      name: string;
      email: string;
    }>();
    
    // Validate
    if (!body.name || !body.email) {
      return c.json({ error: 'Missing required fields' }, 400);
    }
    
    // Save to storage
    const mastra = c.get('mastra');
    const storage = mastra.getStorage();
    const user = await storage.createUser(body);
    
    return c.json({ user }, 201);
  }
});

Using Agents

registerApiRoute('/chat', {
  method: 'POST',
  handler: async (c) => {
    const { message, threadId } = await c.req.json<{
      message: string;
      threadId?: string;
    }>();
    
    const mastra = c.get('mastra');
    const agent = mastra.getAgent('assistant');
    
    const response = await agent.generate(message, {
      memory: threadId ? {
        thread: threadId,
        resource: 'user-123'
      } : undefined
    });
    
    return c.json({
      response: response.text,
      threadId: response.threadId
    });
  }
});

Streaming Response

registerApiRoute('/stream', {
  method: 'POST',
  handler: async (c) => {
    const { message } = await c.req.json<{ message: string }>();
    
    const mastra = c.get('mastra');
    const agent = mastra.getAgent('assistant');
    
    const stream = await agent.stream(message);
    
    return new Response(stream.textStream);
  }
});

Error Handling

registerApiRoute('/data/:id', {
  method: 'GET',
  handler: async (c) => {
    try {
      const id = c.req.param('id');
      const mastra = c.get('mastra');
      const storage = mastra.getStorage();
      
      const data = await storage.getData(id);
      
      if (!data) {
        return c.json({ error: 'Data not found' }, 404);
      }
      
      return c.json({ data });
    } catch (error) {
      console.error('Error fetching data:', error);
      return c.json({ 
        error: 'Internal server error',
        message: error instanceof Error ? error.message : 'Unknown error'
      }, 500);
    }
  }
});

Authentication Check

registerApiRoute('/protected', {
  method: 'GET',
  handler: async (c) => {
    const authHeader = c.req.header('authorization');
    
    if (!authHeader?.startsWith('Bearer ')) {
      return c.json({ error: 'Unauthorized' }, 401);
    }
    
    const token = authHeader.substring(7);
    const user = await verifyToken(token);
    
    if (!user) {
      return c.json({ error: 'Invalid token' }, 401);
    }
    
    return c.json({ message: 'Protected data', user });
  }
});

File Upload

registerApiRoute('/upload', {
  method: 'POST',
  handler: async (c) => {
    const formData = await c.req.formData();
    const file = formData.get('file') as File;
    
    if (!file) {
      return c.json({ error: 'No file provided' }, 400);
    }
    
    // Process file
    const buffer = await file.arrayBuffer();
    const content = Buffer.from(buffer);
    
    // Save to storage
    const mastra = c.get('mastra');
    const fileId = await saveFile(content, file.name);
    
    return c.json({
      message: 'File uploaded successfully',
      fileId,
      filename: file.name,
      size: file.size
    });
  }
});

Request Context

registerApiRoute('/context', {
  method: 'GET',
  handler: async (c) => {
    const requestContext = c.get('requestContext');
    
    // Set values in request context
    requestContext.set('userId', 'user-123');
    requestContext.set('role', 'admin');
    
    // These values are available to agents, tools, etc.
    const mastra = c.get('mastra');
    const agent = mastra.getAgent('assistant');
    
    const response = await agent.generate('Hello', {
      requestContext
    });
    
    return c.json({ response: response.text });
  }
});

Build docs developers (and LLMs) love