Developers

The Vexo API

Put Vexo inside your own product. Render designed emails, write posts from facts you supply, and find real businesses of a kind you describe, each read from its own website. You pay per call, from credit you buy up front. There is no subscription, no invoice, and nothing you owe afterwards.

You need an account, and to make a key you need to sign in with Google or LinkedIn and agree to the API terms. An account made with an email and a password has not been verified, and a key can spend money, so it cannot make one.

Quickstart

Sign up, then make a key in the developer portal. Start with a test key: it spends nothing and answers with sample data where a real answer would cost money. Test keys are limited to 2,000 calls a day.

curl https://touchbasetechnologies.com/vexo/api/v1/email/render \
  -H "Authorization: Bearer vx_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "subject": "Welcome, {{first_name}}",
    "blocks": [{ "type": "heading", "props": { "text": "Welcome, {{first_name}}" } }],
    "variables": { "first_name": "Ada" },
    "brand": { "companyName": "Acme" }
  }'

Authentication

Send the key as a bearer token. Keys look like vx_live_ or vx_test_ followed by 43 characters. A key is shown once, when you make it. Vexo keeps a fingerprint of it, not the key, so it cannot be shown again. Keep it on your server, never in a browser or an app you ship.

  • Each key has its own permissions: it can only call the things you ticked when you made it.
  • Making a key needs a verified sign-in and agreement to the terms, and is written to your workspace's audit log, along with revoking one.
  • Each key can have a monthly spending cap in dollars. Calls past it are refused.
  • Revoking a key stops it at once.

Pricing

A credit is one cent, the same credit the Vexo studio spends. Each call takes its price from your balance before any work is done, and gives back whatever was not delivered: a call that fails costs nothing, a company search is charged per company found, and a search that finds none is free. When the balance cannot cover a call, the call is refused with a 402 and does nothing.

ProductPrice
email.render1 cent per render
content.post1 cent per post
leads.company5 cents per company

Coming next, at these prices: leads.contact (8 cents per contact), campaign.email (1 cent per email), social.publish (2 cents per post), content.image (10 cents per image), video.minute ($2.05 per minute), avatar.minute ($1.94 per minute), avatar.build ($32.50 per presenter). Prices for these are not final until they are released.

The same list is available as JSON from GET https://touchbasetechnologies.com/vexo/api/v1/pricing, with no key.

Render an email

POST /v1/email/render turns one of Vexo's templates, or your own blocks, into table-based HTML that holds up in Outlook, plus a matching plain-text part. List the templates with GET /v1/email/templates, which is free.

POST /v1/email/render
{
  "template": "<a key from /v1/email/templates>",   // or "blocks": [...] with "subject"
  "brand": { "companyName": "Acme", "primaryColor": "#2447d6" },
  "variables": { "first_name": "Ada" },
  "transactional": false
}

200
{ "subject": "...", "html": "<!doctype html>...", "text": "..." }

Merge values are escaped before they reach the page, so a customer's name cannot inject markup into your email.

Write a post

POST /v1/content/posts writes one post for LinkedIn, X, Facebook, Instagram or Threads. It writes from the facts you send and nothing else: a sentence with a number that is in neither your topic nor your facts is cut, and the response says so. It never runs past what the network allows.

POST /v1/content/posts
{
  "topic": "We launched instant quotes",
  "platform": "linkedin",
  "voice": "plain and direct",
  "facts": ["Quotes now take under a minute", "Available to all customers from Monday"]
}

200
{ "text": "...", "platform": "linkedin", "characters": 412, "warnings": [] }

Find companies

POST /v1/leads/search finds real businesses of any kind you describe, in a US state, city or county. Each comes from open map data, is read from its own website, and is checked against the kind you asked for, so a company that is clearly something else is dropped. You say what you sell, and each result carries a reason it fits that is grounded in the company's own words.

POST /v1/leads/search
{
  "kind": "solar installers",
  "region": "Austin, Texas",
  "count": 5,
  "offer": "Quoting software for installers"
}

200
{
  "runId": "run_...",
  "companies": [{ "id": "...", "name": "...", "website": "https://...", "location": "...", "description": "...", "whyFit": "..." }],
  "searchedAs": "Solar installers",
  "skipped": { "alreadyHad": 0, "notAFit": 3, "unverified": 1 }
}

A call returns at most five companies, because each is a website read and a judgement and a call has to finish in about half a minute. If a call times out on your side, fetch what it found, free, with GET /v1/leads/runs/<runId>. The companies are also saved in your Vexo workspace. Data from OpenStreetMap contributors, ODbL.

Errors

Every error has the same shape, with a code your program can act on and a message a person can read.

{ "error": { "code": "insufficient_credit", "message": "This call costs 0.05 dollars and the balance is 0.03. Top up in the dashboard." } }
401invalid_keyMissing, malformed or revoked key.
402insufficient_creditThe balance cannot cover the call. Nothing was done.
402key_cap_reachedThe call would take the key past its monthly cap.
403scope_missingThe key was not given permission for this.
403ip_not_allowedThe key may not be used from this address.
400invalid_requestSomething in the request is missing or wrong. The message says what.
409idempotency_replayThat Idempotency-Key was already used.
429rate_limitedToo many calls a minute for this key.
502upstream_errorThe work could not be completed. You were not charged.

Retries and idempotency

Send an Idempotency-Key header to make a call safe to retry. A key is accepted once: using it again returns a 409 and does nothing, so a retry can never charge you twice. It does not return the first answer, so keep that.

Limits

  • 60 calls a minute per key by default, up to 600. Set it when you make the key.
  • Requests up to 200 KB. A post topic up to 500 characters. Up to 20 facts.
  • Company search is open to the United States for now.
  • Prepaid only. Buy credit in the developer portal. There is nothing to pay afterwards.

Ready to build? Sign up and make a test key. Need something that is not here, such as sending campaigns, publishing to social accounts or avatar video? Those are next, and telling us which you need first decides the order.