Backprompter Server SDK
Call Backprompter agents from a Node.js backend with a server API key. Use this when your own backend talks to Backprompter on behalf of your users.
Overview
The SDK authenticates with an API key and never needs a browser session. It covers agent calls, end-user data, and identity tokens for your own login.
createUserToken.
Get your keys
| Value | Where to find it |
|---|---|
| API key | Dashboard, your app, the Deploy modal. It looks like bp_live_xxxxx.<secret>. Keep it server-side only. |
| App Key | Your app and tenant id, from the same Deploy modal. |
Install
npm install backprompter-server-sdk
This requires Node.js 18 or later, because it uses the built-in fetch.
Quick start
import BackprompterServer from 'backprompter-server-sdk';
const bp = new BackprompterServer({
apiKey: process.env.BACKPROMPTER_API_KEY, // bp_live_xxxxx.<secret>
tenantId: process.env.BACKPROMPTER_APP_KEY, // your App Key
});
const result = await bp.run({
agentId: 'your-agent-name', // or omit to auto-route
userPrompt: 'Summarize this support ticket.',
conversationHistory: [],
profileString: 'Enterprise customer',
});
console.log(result.response); // the agent's reply
// result.agentId, result.artifactType
Run an agent
const result = await bp.run({
userPrompt: 'What changed last quarter?',
// agentId: 'analyst', // omit to auto-route to the best agent
conversationHistory: [], // array of { role, content } pairs
profileString: '', // optional user-profile context
// fileInputs: [], // attachments, see below
// urlInputs: [], // URLs to attach as context
// contextLimit: 120000, // characters of history before auto-summarization
// maxTokens: 1000,
// ragCharBudget: 20000,
// tenantId: 'other-app', // overrides the constructor value for this call
});
Attachments
Inside fileInputs, the key you use decides how the attachment is sent.
| Key | Sent as |
|---|---|
url, dataUrl, base64 | image |
file_url, file_data | document |
Backprompter infers the real type wherever it can. It reads an explicit mimeType,
the data-URL prefix, the file extension, or the leading bytes of base64. It falls back to the
key only when the type cannot be determined.
await bp.run({
agentId: 'analyst',
userPrompt: 'What are the Q3 totals?',
fileInputs: [
{ file_url: 'https://example.com/q3.pdf', filename: 'q3.pdf' }, // document
{ url: 'https://example.com/chart.png' }, // image
],
});
Document support varies by model. OpenAI models accept spreadsheets. Anthropic models accept PDF only, and they reject other types outright. Choose a model that handles what you send.
Keep your own login
Your app can keep its own login. Backprompter never has to see a password. Your backend
exchanges your user id for a session token, and your frontend signs in with that token. The
frontend then reaches every
Browser SDK function, including saveData,
search, file handling, and voice.
// your backend, behind your own session check
app.post('/api/bp-token', requireMyAuth, async (req, res) => {
const { customToken } = await bp.createUserToken({
externalId: req.user.id, // your own user id
email: req.user.email // a label for your dashboard
});
res.json({ customToken });
});
// your frontend, after your own login succeeds
const { customToken } = await fetch('/api/bp-token').then((r) => r.json());
await Backprompter.signInWithCustomToken(customToken);
Backprompter derives a storage id from your tenant id and your external id. The same external id always returns to the same data. You cannot choose the id.
Keep the API key on your server. Only the token reaches the browser. A token is valid for one user of one app.
End-user data from your backend
You can also skip the browser session and do everything from your server. Call
forUser() with your own user id.
const user = bp.forUser('u_8821');
await user.saveData('preferences', { theme: 'dark' });
const prefs = await user.getData('preferences');
await user.deleteData('preferences');
await user.saveConversation(conversationId, messages, { title: 'Support' });
const list = await user.listConversations();
const convo = await user.getConversation(conversationId);
await user.deleteConversation(conversationId);
await user.storeArtifacts([{ name: 'notes.md', content: text }]);
const arts = await user.listArtifacts();
const hits = await user.search('last quarter revenue', { k: 5 });
const ent = await user.getEntitlements();
const { url } = await user.createCheckoutSession({ successUrl, cancelUrl });
Every call reads and writes that person's data only. The API key decides the app. The external id decides the person.
bp.run(), and pass what the
agent should know about the person in profileString.
const profile = await user.getData('profile');
const result = await bp.run({
agentId: 'analyst',
userPrompt: 'What changed?',
profileString: JSON.stringify(profile.data)
});
API key scopes
New API keys carry three scopes.
| Scope | Allows |
|---|---|
run:public | bp.run() |
enduser:data | bp.forUser(...) |
identity:exchange | bp.createUserToken(...) |
Keys generated before these features existed carry run:public only. To use
forUser() or createUserToken(), generate a new key from the Deploy
modal.
A key reaches only the app it was made for. A request naming another app returns 403, even when the same developer owns both.
Payments
An API key never triggers the Backprompter payment gate. Your backend is your own integration, so you decide what a person may do.
Read the entitlement yourself when you want to enforce payment.
const { active, paymentRequired } = await bp.forUser('u_8821').getEntitlements();
if (paymentRequired && !active) {
return res.status(402).json({ error: 'Subscribe first' });
}
The gate applies only to end users signed in with a Backprompter token. That includes users who
signed in with a custom token from createUserToken().
If you collect money outside Backprompter, leave the Backprompter payment settings empty. No gate then applies to anyone.
Notes and limits
- Authenticates with the
x-bp-api-keyheader. Never expose the API key in a browser. tenantIdcan be set in the constructor or per call, asbp.run({ tenantId }).- Uses the hosted Backprompter backend by default. No URL configuration is needed.
- Requires Node.js 18 or later.