@mappa-ai/mappa-node
v2.0.11
Published
Official TypeScript/Node SDK for the Mappa API
Maintainers
Readme
@mappa-ai/mappa-node
Behavioral intelligence for your app. Type-safe. Async-first. Production-ready.
Install
# npm
npm install @mappa-ai/mappa-node
# yarn
yarn add @mappa-ai/mappa-node
# pnpm
pnpm add @mappa-ai/mappa-node
# bun
bun add @mappa-ai/mappa-nodeRuntime support
Runs anywhere fetch runs. Node, Bun, Deno, Cloudflare Workers. Browser blocked by default — your API key stays secret.
Security
Your API key is secret. We enforce it.
- Keep
MAPPA_API_KEYserver-side. - Proxy requests through your backend.
- Browser calls throw unless you set
dangerouslyAllowBrowser: true.
Choose a workflow
Three paths. Pick yours.
| Method | When to use |
| --- | --- |
| generateFromFile / generateFromUrl | One call. Done. |
| createJob + webhook | Fire and forget. We call you. |
| createJob + wait() / stream() | Stay in control. |
Webhooks — the production path
Submit jobs. Move on. Mappa calls your endpoint when it's done. Signatures included.
Publish
One field. That's it.
import { Mappa } from "@mappa-ai/mappa-node"
const mappa = new Mappa({ apiKey: process.env.MAPPA_API_KEY! })
const receipt = await mappa.reports.createJobFromFile({
file: audioBlob,
output: { template: "general_report" },
target: { strategy: "dominant" },
webhook: {
url: "https://your-app.com/api/webhooks/mappa",
headers: { "x-tenant-id": "tenant_123" },
},
})
console.log(receipt.jobId)Already have media uploaded? Same idea.
await mappa.reports.createJob({
media: { mediaId: "media_abc123" },
output: { template: "general_report" },
target: { strategy: "dominant" },
webhook: { url: "https://your-app.com/api/webhooks/mappa" },
})Consume
Verify. Parse. React.
import { Mappa } from "@mappa-ai/mappa-node"
const mappa = new Mappa({ apiKey: process.env.MAPPA_API_KEY! })
export async function POST(req: Request): Promise<Response> {
const payload = await req.text()
await mappa.webhooks.verifySignature({
payload,
headers: Object.fromEntries(req.headers),
secret: process.env.MAPPA_WEBHOOK_SECRET!,
})
const event = mappa.webhooks.parseEvent(payload)
if (event.type === "report.completed") {
const report = await mappa.reports.get(event.data.reportId)
console.log("done", report.id)
return new Response("ok", { status: 200 })
}
if (event.type === "report.failed") {
console.error("failed", event.data.jobId, event.data.error.code)
return new Response("ok", { status: 200 })
}
return new Response("ignored", { status: 200 })
}Polling — when you want to wait
Sometimes you need the answer now.
wait()
import { Mappa } from "@mappa-ai/mappa-node"
const mappa = new Mappa({ apiKey: process.env.MAPPA_API_KEY! })
const media = await mappa.files.upload({ file: audioBlob })
const job = await mappa.reports.createJob({
media: { mediaId: media.mediaId },
output: { template: "general_report" },
target: { strategy: "dominant" },
})
const report = await job.handle?.wait()
console.log(report?.id)stream()
for await (const event of job.handle?.stream() ?? []) {
if (event.type === "stage") {
console.log(event.stage, event.progress)
}
}Helpers
generateFromFile
Upload, process, return. One call.
const report = await mappa.reports.generateFromFile({
file: audioBlob,
output: { template: "general_report" },
target: { strategy: "dominant" },
})
console.log(report.id)generateFromUrl
Got a URL? We fetch it.
const report = await mappa.reports.generateFromUrl({
url: "https://example.com/recording.wav",
output: { template: "general_report" },
target: { strategy: "dominant" },
})
console.log(report.id)Node/Bun file paths
Working with file paths? Use the /node subpath.
import { Mappa } from "@mappa-ai/mappa-node"
import { generateReportFromPath, uploadFromPath } from "@mappa-ai/mappa-node/node"
const mappa = new Mappa({ apiKey: process.env.MAPPA_API_KEY! })
const media = await uploadFromPath(mappa, { path: "./recording.wav" })
const report = await generateReportFromPath(mappa, {
path: "./recording.wav",
output: { template: "general_report" },
target: { strategy: "dominant" },
})
console.log(media.mediaId, report.id)Error handling
Things break. We tell you why.
import { isInsufficientCreditsError, isMappaError, isStreamError } from "@mappa-ai/mappa-node"
try {
// ...
} catch (err) {
if (isInsufficientCreditsError(err)) {
console.error(err.required, err.available)
return
}
if (isStreamError(err)) {
console.error(err.jobId, err.retryCount)
return
}
if (isMappaError(err)) {
console.error(err.requestId, err.code, err.message)
}
}Scope
API-key workflows. Reports, files, jobs, webhooks, feedback, entities. Billing lives in the dashboard.
Questions? api-docs.mappa.ai
For SDK maintenance, see README_INTERNAL.md.
