Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/elysiajs/documentation/llms.txt

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

Every awaited Eden Treaty call resolves to an object with the following properties:
PropertyTypeDescription
dataT | nullThe response body when status is 2xx
errorE | nullThe response body when status is >= 3xx
responseResponseThe raw Web Standard Response object
statusnumberThe HTTP status code
headersFetchRequestInit['headers']The response headers
Until you handle the error case, data is typed as T | null. Once you narrow the error away, TypeScript unwraps it to T.

Basic error handling

import { Elysia, t } from 'elysia'
import { treaty } from '@elysia/eden'

const app = new Elysia()
    .post('/user', ({ body: { name }, status }) => {
        if (name === 'Otto') return status(400)
        return name
    }, {
        body: t.Object({
            name: t.String()
        })
    })
    .listen(3000)

const api = treaty<typeof app>('localhost:3000')

const submit = async (name: string) => {
    const { data, error } = await api.user.post({ name })

    // type: string | null
    console.log(data)

    if (error)
        switch (error.status) {
            case 400:
                throw error.value

            default:
                throw error.value
        }

    // error is handled — type is now: string
    return data
}
When the server returns a status >= 300, data is always null and error contains the response value. When the status is 2xx, error is null and data contains the value.

Stream responses

Eden Treaty treats generator-based routes and Server-Sent Events as AsyncGenerator. Use a for await loop to consume chunks as they arrive.
import { Elysia } from 'elysia'
import { treaty } from '@elysia/eden'

const app = new Elysia()
    .get('/ok', function* () {
        yield 1
        yield 2
        yield 3
    })

const { data, error } = await treaty(app).ok.get()
if (error) throw error

for await (const chunk of data)
    console.log(chunk)

Utility types

Use Treaty.Data<T> and Treaty.Error<T> to extract the response types statically without making a call. Pass either the method function or an awaited response object.
import { Elysia, t } from 'elysia'
import { treaty, Treaty } from '@elysia/eden'

const app = new Elysia()
    .post('/user', ({ body: { name }, status }) => {
        if (name === 'Otto') return status(400)
        return name
    }, {
        body: t.Object({
            name: t.String()
        })
    })
    .listen(3000)

const api = treaty<typeof app>('localhost:3000')

// Extract data type from the method reference
type UserData = Treaty.Data<typeof api.user.post>

// Or from an awaited response
const response = await api.user.post({ name: 'Saltyaom' })
type UserDataFromResponse = Treaty.Data<typeof response>

// Extract error type
type UserError = Treaty.Error<typeof api.user.post>
These utility types are useful when you want to type function parameters or return values that mirror an Eden Treaty call without calling the endpoint at the type level.

Build docs developers (and LLMs) love