@trillboards / api-client
Trillboards DOOH合作伙伴API的官方TypeScript SDK。
安装
npm install @trillboards/api-client
要求Node.js 18+。REST使用本机 fetch; 媒体购买使用官方MCP客户端,流媒体使用其共享的SSE解析器。继续在服务器应用程序中购买凭据。
快速入门
import { TrillboardsClient } from '@trillboards/api-client';
const client = new TrillboardsClient({
apiKey: 'trb_partner_xxxxx',
});
// List screens
const { data: screens } = await client.screens.list({ limit: 10 });
// Get analytics
const { data: analytics } = await client.analytics.get({ period: 'week' });
// Get earnings
const { data: earnings } = await client.earnings.get({ period: 'month' });
资源
| 资源 | 方法 |
|---|---|
client.screens | list, get, create, delete, getDisplaySettings, patchDisplaySettings, updateDisplaySettings, batchUpdateDisplaySettings |
client.devices | list, get, create, createBatch, delete, heartbeat |
client.impressions | create, createBatch |
client.analytics | get |
client.earnings | get |
client.webhooks | list, create, update, delete, test |
client.fleet | pushCommand, listCommands |
client.audience | getLive, getHeatmap, getStats |
client.data | getVenueIntelligence, getUsage, listScreens, getHistory, getAudience, query, stream |
client.errors | list, get |
client.billing | setup, createCreditCheckout, purchaseCredits, getUsageSummary, get, getStripeStatus, requestPayout |
client.mediaBuys | getProducts, discoverInventory, listAccounts, syncAccounts, create, list, update, syncCreatives, getDelivery, close |
client.creativeExperiments | create, get, configureBrand, generate, importCreative, review, registerVariants, updatePolicy, getRewards, stop |
建立并运行一个创造性的反馈循环
使用 创造性的AI反馈循环 对于完整的购买,创造性的评论,服务和纠正意识奖励的例子。相同的合作伙伴密钥适用于REST和本地MCP购买工具。
创建一个信用结帐与稳定的关键为这个确切的购买,然后打开返回的条纹URL:
const checkout = await client.billing.createCreditCheckout(
{ tier: 'tier_500' },
{ idempotencyKey: 'my-first-credit-checkout-v1' },
);
console.log(checkout.checkout_url);
付款完成后,读取承诺余额:
const balance = await client.billing.getUsageSummary();
console.log(balance.credit_balance_cents, balance.credit_reserved_cents);
余额和计量金额保留其精确的十进制字符串。节省的付款方式本身并不能为交付提供资金。媒体使用其认可的引用;API使用使用已发布的API收费标准。
直接 purchaseCredits 可以返回 requires_action: true 与一个 client_secret。完成支付的Stripe认证,然后读取已提交的余额;保持其 operation_id 和稳定键。SDK不加更改地返回这些字段。Stripe Checkout在返回的浏览器流中处理身份验证。
在创建购买之前,发现您的帐户和实时产品目录:
try {
const accounts = await client.mediaBuys.listAccounts();
const products = await client.mediaBuys.getProducts({
brief: 'Transit screens for a creative attention test',
pagination: { max_results: 10 },
});
console.log(accounts.accounts, products.products, products.pagination);
} finally {
await client.mediaBuys.close();
}
client.mediaBuys.create 接受原生AdCP请求,包括帐户、航班、产品/定价选项标识符、预算和稳定性 idempotency_key. list 接受 media_buy_ids 和分页; update 接受本机修订。保存 media_buy_id 和 packages[].package_id 用于 creativeExperiments.create。MCP任务 status 描述任务执行情况;返回的媒体购买生命周期、资金和节制描述了交付准备情况。始终释放MCP连接 mediaBuys.close() 当完成。
历史数据和实时数据
Data API资源需要其端点声明的作用域: read:live, read:historical 或者 stream:live。屏幕列表分页将不变地返回为 has_more 和 next_offset。有限的历史读取保存了未测量的值 null.
const history = await client.data.getHistory('YOUR_SCREEN_ID', {
since: '2026-10-01T00:00:00Z',
until: '2026-10-02T00:00:00Z',
limit: 100,
});
console.log(history.metrics);
const controller = new AbortController();
try {
for await (const event of client.data.stream({}, { signal: controller.signal })) {
console.log(event.event, event.data);
if (event.event === 'audience') break;
}
} finally {
controller.abort();
}
向前流 connected, audience 和带内 error 事件。中断迭代或中止将关闭连接。它是一个活动尾巴:显式地重新连接并使用有界的历史读取来恢复历史数据。创造性的奖励更正使用指南的标准密钥/修订扫描协议。
MCP工具故障抛出 McpToolError 用精确的 tool 和原始 result,包括结构化错误代码和收据。来自官方MCP传输的协议/HTTP错误保持不变。REST故障使用 TrillboardsError.
内容符合
await client.screens.patchDisplaySettings('SCREEN_ID', {
content_fit: {
advertisements: 'fill',
default_streams: 'fill',
self_promo: 'fit',
},
});
await client.devices.createBatch({
defaults: {
display_settings: {
content_fit: { advertisements: 'fill', self_promo: 'fill' },
},
},
devices: [
{ device_id: 'screen-001' },
{
device_id: 'screen-002',
display_settings: { content_fit: { self_promo: 'fit' } },
},
],
});
fit 保留了充分的创意和可能的信箱; fill 覆盖屏幕
并可能剪掉它的边缘。省略 content_fit 保持现有的行为不变。
错误处理
import { TrillboardsClient, TrillboardsError } from '@trillboards/api-client';
try {
await client.screens.get('nonexistent');
} catch (err) {
if (err instanceof TrillboardsError) {
console.log(err.code); // 'screen_not_found'
console.log(err.statusCode); // 404
console.log(err.docsUrl); // 'https://api.trillboards.com/docs/errors#screen_not_found'
if (err.isRateLimited) {
const retryAfter = err.retryAfter; // seconds from Retry-After header
}
}
}
Webhook验证
Trillboards网钩带有条纹样式的复合签名头
X-Trillboards-Signature: t=<timestamp>,v0=<hex>,v1=<hex> 还有一个单独的
X-Trillboards-Timestamp: <unix_seconds> 为冗余。
验证器接受任意一种格式,并在300秒之外拒绝有效载荷 默认为重播窗口。
import { Webhooks } from '@trillboards/api-client';
// Use express.raw for the webhook route so req.body is the exact signed bytes
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
try {
const event = Webhooks.constructEvent(
req.body, // raw Buffer or string (NOT JSON.parsed)
req.headers, // IncomingHttpHeaders — case-insensitive lookup
process.env.WEBHOOK_SECRET!,
);
console.log('Event:', event.event, event.data);
res.sendStatus(200);
} catch (err) {
// TrillboardsError with code "webhook_signature_invalid"
res.sendStatus(401);
}
});
覆盖重放窗口公差(默认300秒):
const event = Webhooks.constructEvent(req.body, req.headers, secret, {
tolerance: 600, // 10 minutes
});
从0.2.0升级: 0.2.0调用形状
Webhooks.constructEvent(payload, signatureString, secret)生产 针对生产服务器的验证失败,因为服务器 迹象${timestamp}.${payload}而0.2.0验证者签名payload只有。0.3.0的验证器处理两种格式,并增加了重放保护。 迁移到新环境Webhooks.constructEvent(payload, req.headers, secret)电话的形状。0.2.0形状保留为Webhooks.constructEventLegacy对于一个次要版本(记录弃用警告)。
完整的webhook合同: https://api.trillboards.com/docs/integrations/webhook-signature-verification.md
配置
const client = new TrillboardsClient({
apiKey: 'trb_partner_xxxxx', // Required
baseUrl: 'https://api.trillboards.com', // Optional, defaults to production
version: '2024-01-15', // Optional, sent as Trillboards-Version header
});
许可证
麻省理工学院