Brand()

The running jobjob_7Hq2 · working · $49.00 held

Brand({...}) is optional, in brand.ts beside services/. It sets the brand's domain, its own words, the credentials it holds, its family, tenants, practice workspaces, fee policy and payouts. Without it, the brand is package.json's name.

Run
cat brand.ts
magic values: none
import { Brand } from 'services.dev'

export default Brand({
  name: 'Lingua',
  domain: 'lingua.example',
})
Run
npx services.dev check
magic values: none
brand.ts · 2 lines · Lingua · lingua.example
Call
→ GET /.well-known/agents.json
magic values: none
  name     lingua.example
  openapi  https://lingua.example/openapi.json
Call
→ GET /openapi.json
magic values: none
  servers  https://lingua.example · http://localhost:8787

What Brand() takes: optional, beside services/. Without it the brand is package.json's name.

KeyWrittenLeft outDoes
namestringpackage.json's nameThe brand's name on every surface.
domainstringnoneIts canonical origin: agents.json's name, the absolute openapi and doc_url links, openapi's servers. Localhost still serves them.
words{ <generic word>: string }noneThe brand's own words for the generic ones, on every Layer B surface: paths, events, commands, tools, SDK names, docs, the Site and the apps. Each plural is the word's own.
also{ <op id>: path | path[] }nonePaths of the brand's own at which an operation is also served, beside the row's: { 'member.ledger.get': '/conflicts' }. A declared column of the operation registry, like words: the same handler, the same callers, in the HTTP column of every surface that renders it. An id that names no operation, or a path that collides with one services.dev serves, fails word_collision.
credentials{ <credential>: { verify, fresh?, via? } }noneCredentials the brand itself holds, verified and kept fresh like a member's. A rules row names one with { brand }; while one is unverified or stale, an act that needs it answers brand_unverified.
fees{ shares?: boolean; percent_pay?: boolean; split_professional_fee?: boolean; percent_member_fee?: false }noneFee policy: false forbids a fee form on every Service.
familystring[]noneSibling brands one buyer key opens.
tenantsboolean | { limits: ('max_fee' | 'regions' | 'humans_earlier')[] }noneIntegrators who resell your Services as their own offers.
workspacesbooleannoneBuyers may bring their own professionals into a scoped practice workspace.
payouts{ rail: 'stripe'; schedule?: 'same-day' | 'weekly' }noneHow services.dev's take and members' pay move.
descriptorstring, up to 22 charactersthe domain, uppercasedHow your charge reads on the buyer's statement, each Service's short name after it.
tax'stripe' | falsefalseTax on your charges, calculated by Stripe Tax and collected as its own line, outside the take.
dunning{ for?: Within; ask?: boolean }{ for: '14d', ask: true }How long a failed charge retries, and whether the buyer is asked to update how they pay.
disputes{ evidence?: 'auto' | 'review'; prevent?: { refund_under?: number } }{ evidence: 'auto' }Whether dispute evidence is sent for you or waits for your review, and the warned charges refunded before a dispute opens.
calendarCalendarnone: dates close at 23:59 UTC and nothing rollsWhere the brand's dates fall: the zone its deadlines are kept in, its weekends and closed days, the minute a due date closes and the minute rungs ring, and whether a date on a closed day rolls to the next open one. A Service may set its own.
OpAPICLIMCPSDKSiteDocsApp
brand.cardGET /.well-known/agents.json/.well-known/agents.json
brand.openapiGET /openapi.json/openapi.json

Operations has every column of every row.

Run
npx services.dev check
magic values: member = mbr_eligible
brand.ts · 10 lines · legal · api.lawyer · words job → matter, subject → asset, task → review, member → signer, pool → network, end → outcome

A filing brand that holds its own credential

Run
cat brand.ts
magic values: metadata.sandbox.brand = verified, metadata.sandbox.brand = stale
import { Brand } from 'services.dev'

// A filing brand that e-files under its own e-file number: a credential the brand itself holds,
// verified by its own verifier and kept fresh. On a test key the sandbox stands in for the verifier.
export default Brand({
  domain: 'filings.example',
  credentials: { efin: { verify: 'https://verify.example.test/efin', fresh: '30d', via: 'the e-file application' } },
})
CodeCategoryHTTPWhy
brand_unverifiedunavailable403A credential the brand itself holds is unverified or stale, so the act it covers waits. Nothing was charged.
check gateWhy
word_collisionA Brand.words value takes a generic word, a word an operation's id is spelled with or a path services.dev already serves, or makes two rows render the same, so two things would read the same.
brand_credential_missingA rules row names a credential the brand holds, and the Brand doesn't declare it.