Serving the Inngest API
Inngest works by serving an HTTP API endpoint which exposes your functions for us to call on-demand. The first thing you'll need to do is to add and serve the Inngest API in your project.
Setting up the API
Inngest provides a serve()
handler which adds an API endpoint to your router. You should always
serve our API at /api/inngest
, as this makes automated deploys much easier. If you need to
change the API URL skip to configuring the API Path.
// All serve handlers have the same arguments:
serve({
client: inngest, // a client created with new Inngest()
functions: [fnA, fnB], // an array of Inngest functions to serve, created with inngest.createFunction()
/* Optional extra configuration */
});
We provide framework-specific bindings to make this easy for common platforms:
- Astro
- AWS Lambda
- Bun.serve()
- Cloudflare
- DigitalOcean functions
- Express
- Fastify
- Fresh (Deno)
- Google Cloud Functions
- H3
- Koa
- Next.js
- Redwood
- Remix
- SvelteKit
- Custom
Each of these bindings wrap our base API which implemnts the core logic, so adding support for new frameworks is easy. Want us to add support for another platform? Come say hi in our discord or drop us a note.
Signing key
You'll need to assign your signing key to an INNGEST_SIGNING_KEY
environment variable in your hosting
provider or .env
file locally. This lets the SDK securely communicate with Inngest. If you can't
provide this as a signing key, you can pass it in to serve
when setting up your framework. Read
the reference for more information.
Framework: Astro v3.8.0+
Add the following to ./src/pages/api/inngest.ts
:
import { serve } from "inngest/astro";
import { functions, inngest } from "../../inngest";
export const { GET, POST, PUT } = serve({
client: inngest,
functions,
});
See the Astro example for more information.
Framework: AWS Lambda v1.5.0+
We recommend using Lambda function URLs to trigger your functions, as these require no other configuration or cost.
Alternatively, you can use an API Gateway to route requests to your Lambda. The handler supports API Gateway V1 and API Gateway V2. If you are running API Gateway behind a proxy or have some other configuration, you may have to specify the serveHost
and servePath
options when calling serve()
to ensure Inngest knows the URL where you are serving your functions. See Configuring the API path for more details.
import { serve } from "inngest/lambda";
import { inngest } from "./client";
import fnA from "./fnA"; // Your own function
export const handler = serve({
client: inngest,
functions: [fnA],
});
Bun.serve()
You can use the inngest/bun
handler with Bun.serve()
for a lightweight
Inngest server.
import { serve } from "inngest/bun";
import { functions, inngest } from "./inngest";
Bun.serve({
port: 3000,
fetch(request: Request) {
const url = new URL(request.url);
if (url.pathname === "/api/inngest") {
return serve({ client: inngest, functions })(request);
}
return new Response("Not found", { status: 404 });
},
});
Framework: Cloudflare
You can import the Inngest API server when using Cloudflare pages functions or workers within /functions/api/inngest.js
:
import { serve } from "inngest/cloudflare";
import { inngest } from "../../inngest/client";
import fnA from "../../inngest/fnA"; // Your own function
export const onRequest = serve({
client: inngest,
functions: [fnA],
});
Framework: DigitalOcean Functions
The DigitalOcean serve function allows you to deploy Inngest to DigitalOcean serverless functions. Because DigitalOcean doesn't provide the request URL in its function arguments, you must include the function URL and path when configuring your handler:
import { serve } from "inngest/digitalocean";
import { inngest } from "./src/inngest/client";
import fnA from "./src/inngest/fnA"; // Your own function
const main = serve({
client: inngest,
functions: [fnA],
// Your digitalocean hostname. This is required otherwise your functions won't work.
serveHost: "https://faas-sfo3-your-url.doserverless.co",
// And your DO path, also required.
servePath: "/api/v1/web/fn-your-uuid/inngest",
});
// IMPORTANT: Makes the function available as a module in the project.
// This is required for any functions that require external dependencies.
module.exports.main = main;
Framework: Express
You can serve Inngest functions within your existing Express app, deployed to any hosting provider like render, fly, AWS, K8S, etc:
import { serve } from "inngest/express";
import { inngest } from "./src/inngest/client";
import fnA from "./src/inngest/fnA"; // Your own function
// Important: ensure you add JSON middleware to process incoming JSON POST payloads.
app.use(express.json());
app.use(
// Expose the middleware on our recommended path at `/api/inngest`.
"/api/inngest",
serve({ client: inngest, functions: [fnA] })
);
You must ensure you're using the express.json()
middleware otherwise your functions won't be
executed. Note - You may need to set express.json()
's limit
option to something higher than the default
100kb
to support larger event payloads and function state.
Framework: Fastify v2.6.0+
You can serve Inngest functions within your existing Fastify app.
We recommend using the exported inngestFastify
plugin, though we also expose a generic serve()
function if you'd like to manually create a route.
import Fastify from "fastify";
import inngestFastify from "inngest/fastify";
import { inngest, fnA } from "./inngest";
const fastify = Fastify();
fastify.register(inngestFastify, {
client: inngest,
functions: [fnA],
options: {},
});
fastify.listen({ port: 3000 }, function (err, address) {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});
Framework: Fresh (Deno)
Inngest works with Deno's Fresh
framework via the esm.sh
CDN. Add the serve handler to ./api/inngest.ts
as follows:
import { serve } from "https://esm.sh/inngest/deno/fresh";
import { inngest } from "./src/inngest/client.ts";
import fnA from "./src/inngest/fnA"; // Your own function
export const handler = serve({
client: inngest,
functions: [fnA],
});
Framework: Google Cloud Functions
Google's Functions Framework has an Express-compatible API which enables you to use the Express serve handler to deploy your functions to Google's Cloud Functions or Cloud Run. This is an example of a function
import * as ff from "@google-cloud/functions-framework";
import { serve } from "inngest/express";
import { inngest } from "./src/inngest/client";
import fnA from "./src/inngest/fnA"; // Your own function
ff.http(
"inngest",
serve({
client: inngest,
functions: [fnA],
})
);
You can run this locally with npx @google-cloud/functions-framework --target=inngest
which will serve your Inngest functions on port 8080
.
Framework: H3 v2.7.0+
Inngest supports H3 and frameworks built upon it. Here's a simple H3 server that hosts serves an Inngest function.
index.js
import { createApp, eventHandler, toNodeListener } from "h3";
import { serve } from "inngest/h3";
import { createServer } from "node:http";
import { inngest } from "./inngest/client";
import fnA from "./inngest/fnA";
const app = createApp();
app.use(
"/api/inngest",
eventHandler(
serve({
client: inngest,
functions: [fnA],
})
)
);
createServer(toNodeListener(app)).listen(process.env.PORT || 3000);
See the github.com/unjs/h3 repository for more information about how to host an H3 endpoint.
Framework: Koa v3.6.0+
Add the following to your routing file:
import { serve } from "inngest/koa";
import Koa from "koa";
import bodyParser from "koa-bodyparser";
import { functions, inngest } from "./inngest";
const app = new Koa();
app.use(bodyParser()); // make sure we're parsing incoming JSON
const handler = serve({
client: inngest,
functions,
});
app.use((ctx) => {
if (ctx.request.path === "/api/inngest") {
return handler(ctx);
}
});
See the Koa example for more information.
Framework: Next.js
Inngest has first class support for Next.js API routes, allowing you to easily create the Inngest API. Both the App Router and the Pages Router are supported. For the App Router, Inngest requires GET
, POST
, and PUT
methods.
// src/app/api/inngest/route.ts
import { serve } from "inngest/next";
import { inngest } from "../../../inngest/client";
import fnA from "../../../inngest/fnA"; // Your own functions
export const { GET, POST, PUT } = serve({
client: inngest,
functions: [fnA],
});
Streaming v1.8.0+
Next.js Edge Functions hosted on Vercel can also stream responses back to Inngest, giving you a much higher request timeout of 15 minutes (up from 10 seconds on the Vercel Hobby plan!).
To enable this, set your runtime to "edge"
(see Quickstart for Using Edge Functions | Vercel Docs) and add the streaming: "allow"
option to your serve handler:
Next.js 13+
export const runtime = "edge";
export default serve({
client: inngest,
functions: [...fns],
streaming: "allow",
});
Older versions (Next.js 12)
export const config = {
runtime: "edge",
};
const handler = serve({
client: inngest,
functions: [...fns],
streaming: "allow",
});
For more information, check out the Streaming page.
Framework: Nuxt v0.9.2+
Inngest has first class support for Nuxt server routes, allowing you to easily create the Inngest API.
Add the following within ./server/api/inngest.ts
:
import { serve } from "inngest/nuxt";
import { inngest } from "~~/inngest/client";
import fnA from "~~/inngest/fnA"; // Your own function
export default defineEventHandler(
serve({
client: inngest,
functions: [fnA],
})
);
Framework: Redwood
You can add Inngest to Redwood easily. Add the following to
api/src/functions/inngest.ts
:
import { serve } from "inngest/redwood";
import { inngest } from "src/inngest/client";
import fnA from "src/inngest/fnA"; // Your own function
export const handler = serve({
client: inngest,
functions: [fnA],
servePath: "/api/inngest",
});
You should also update your redwood.toml
to add apiUrl = "/api"
, ensuring your API is served
at the /api
root.
Framework: Remix
You can add Inngest to Remix easily. Add the following to ./app/routes/api.inngest.ts
for Remix v2 (or ./app/routes/api/inngest.ts
for Remix v1):
// app/routes/api.inngest.ts
// (for Remix 1, use app/routes/api/inngest.ts)
import { serve } from "inngest/remix";
import { inngest } from "~/inngest/client";
import fnA from "~/inngest/fnA";
const handler = serve({
client: inngest,
functions: [fnA],
});
export { handler as action, handler as loader };
Streaming v2.3.0+
Remix Edge Functions hosted on Vercel can also stream responses back to Inngest, giving you a much higher request timeout of 15 minutes (up from 10 seconds on the Vercel Hobby plan!).
To enable this, set your runtime to "edge"
(see Quickstart for Using Edge Functions | Vercel Docs) and add the streaming: "allow"
option to your serve handler:
export const config = {
runtime: "edge",
};
const handler = serve({
client: inngest,
functions: [...fns],
streaming: "allow",
});
For more information, check out the Streaming page.
Framework: SvelteKit v3.5.0+
Add the following to ./src/routes/api/inngest/+server.ts
:
import { functions, inngest } from '$lib/inngest';
import { serve } from 'inngest/sveltekit';
export const { GET, POST, PUT } = serve({ client: inngest, functions });
See the SvelteKit example for more information.
Reference
For more information about the serve
handler, read the the reference guide, which includes: