• Home
  • Vision
  • Audio
  • Docs
  • GitHub
Sarvam Logo

Vision Server Queue

Install Vision server with Cloudflare Queue-based webhook processing.

Because Sarvam Document Intelligence API doesn't work even if you pass webhook url. This is just a temperary work around.

Install

bunx shadcn@latest add rajatsandeepsen/sarvam-simple/vision-server-queue

Environment Variable

Get your key from sarvam.ai

SARVAM_API_KEY=your_api_key_here

Usage

import { env } from "env";
import { Hono } from "hono";
import { getVisionServerWithQueue } from "./sarvam/vision/server-queue";
 
const app = new Hono().basePath("/api");
 
const { server, queue } = getVisionServerWithQueue({
	SARVAM_API_KEY: env.SARVAM_API_KEY,
	webSocket: true,
	kvBinding: "KEYVALUE",
	webHook: {
		queue: {
			binding: "QUEUE",
			// pollDelaySeconds: 30,
		},
		baseUrl: "https://simple.sarvam.workers.dev/api/vision",
		sendEmail: async (email, files) => {
			// files => [{ filename, url }]
		},
	},
});
 
app.route("/vision", server);
 
export default {
	fetch: app.fetch,
	queue,
};

Flow

  1. POST /vision/upload returns { id } and stores job mapping in KV.
  2. Sarvam calls your webhook route.
  3. Queue handler checks job status using KV + job id mapping.
  4. If job is still running, message is requeued (default 30s delay).
  5. On completion, download URLs are fetched and sendEmail(email, files) is called.

Required bindings

  • KV binding name used in kvBinding (example: KEYVALUE)
  • Queue binding name used in webHook.queue.binding (example: QUEUE)

If queue binding is missing, messages are retried using msg.retry() fallback behavior.

{
	"$schema": "node_modules/wrangler/config-schema.json",
	// rest of the config
	"kv_namespaces": [
		{
			"binding": "KEYVALUE",
			"id": "<kv_id>",
			"preview_id": "<kv_id>"
		}
	],
	"queues": {
		"producers": [
			{
				"binding": "QUEUE",
				"queue": "<queue_name>"
			}
		],
		"consumers": [
			{
				"queue": "<queue_name>",
				"max_batch_size": 10,
				"dead_letter_queue": "my-queue-dlq"
			}
		]
	}
}