Developers

The API is small. The object model is the part that trips people up: an action is what happens, a rule is when, a package pairs them, and a VCode carries packages.

VCode integrates through the VPlatform Client API. The API is small and the endpoints are unsurprising. What trips people up is the object model, so that is what this page leads with.

The one thing to understand. A VCode does not contain a behaviour. It points at one or more packages. A package is a pairing of one action (what should happen) with any number of rules (when it should happen). Get that right and the rest of the API is CRUD.

How resolution works

01 Physical VCode On the item
02 Scanner or SDK App or your own
03 VPlatform Identifies the code
04 Rules Who, where, when
05 Your application Receives the action
Every resolution is written to history, including refusals
A scan is a question put to the platform. The symbol carries no destination, so the answer is decided at 03 and 04, not at 01.

The object model

Object What it is Endpoint
Action What happens on a successful scan. Open a URL, return text, hand over a contact card, deep link into an app, return true or false, or something custom. /actions
Rule A condition tested at scan time. Location, date and time, platform, single scan, email, invalidate, boolean. /rules
Package One action plus the rules that gate it. This is the unit you attach to a code. /packages
VCode The identity itself. Carries package IDs, an optional scan budget and an optional expiry date. /vcodes

A code with two packages can behave two ways from one printed symbol, because each package carries its own rules and the platform picks the one whose conditions are met.

Authentication

Two schemes are supported. Server-to-server integrations use an API key header:

X-VPLATFORM-API-KEY: your-key

User-context calls use a bearer token obtained from the login endpoint, which returns an accessToken and a refreshToken. Refresh through POST /auth/refresh rather than logging in again.

curl -X POST https://api.vplatform.io/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"you@example.com","password":"..."}'

Quickstart: a working VCode in two calls

There is a shortcut endpoint that creates the action, the package and the code in one request. Use it to prove the integration before building anything.

curl -X POST https://api.vplatform.io/vcodes/create-url \
  -H 'Authorization: Bearer <accessToken>' \
  -H 'Content-Type: application/json' \
  -d '{
        "title": "First code",
        "description": "Proving the integration",
        "url": "https://example.com/hello",
        "inapp_browser": true
      }'

The response carries the code’s uti, which is its identifier. Fetch the symbol itself as PNG or SVG:

GET https://api.vplatform.io/vcodes/{uti}/png
GET https://api.vplatform.io/vcodes/{uti}/svg

Print it, scan it, and you have an end-to-end integration. Everything below is refinement.

The full sequence

When you need rules, build the objects in dependency order.

1. Create the action. The data object is discriminated on type.

POST /actions
{
  "title": "Open the product page",
  "data": { "type": "url", "url": "https://example.com/p/123", "inapp_browser": true }
}

2. Create the rules. Same pattern, discriminated on type.

POST /rules
{
  "title": "Venue only",
  "description": "Resolve inside the boundary",
  "data": { "type": "geofence", "geofenceType": "radius",
            "latitude": 53.4808, "longitude": -2.2426, "radius": 250 }
}

3. Create the package, pairing the action with the rules.

POST /packages
{
  "title": "Gate entry",
  "description": "Entry, inside the venue only",
  "actionId": "<action id>",
  "rules": [ "<rule id>" ]
}

4. Create the VCode and attach the package.

POST /vcodes
{
  "title": "Seat C12-8",
  "packageIds": [ "<package id>" ],
  "allowHistory": true,
  "expireAfterScans": 1
}

What a scan can return

Action types, by the type discriminator:

  • url, open a destination, optionally in an in-app browser
  • text and dynamic_text, return content directly
  • contact_card, return contact details
  • app_link, deep link into an application
  • true_false, return a boolean, which is the one to use for an authenticity check
  • nft
  • custom, return your own payload for your application to interpret

Rules

Rule types, by the type discriminator:

  • geofence, by radius or polygon
  • datetime, start and end dates plus hours and minutes of the day
  • platform, one of all, ios, android, web
  • single_scan, with options from ONCE_ONLY through per user, per device, per day, week, month and year
  • email, allow and block lists by address or domain
  • invalidate, for named user IDs
  • boolean, matched on a value your integration supplies

Most rules also accept an inverseAction, which is how one code returns a different response instead of simply refusing.

Resolving a scan

Two endpoints, and the distinction matters. POST /scan is a scan by a camera and carries the context the rules need. POST /open is a lookup by UTI without a scan event.

POST /scan
{
  "uti": "<uti>",
  "userId": "<user id>",
  "deviceId": "<device id>",
  "latitude": 53.4808,
  "longitude": -2.2426,
  "platform": "ios"
}

Send the context you have. Omitting latitude and longitude means a geofence rule cannot be satisfied, and omitting userId means holder rules cannot be.

History and statistics

  • GET /history and GET /history/{id} for the scan record.
  • GET /vcodes/{id}/statistics for totals per code, including unique scans, unique locations, unique users and devices, and the iOS and Android split.
  • PUT /vcodes/{id}/state to revoke or reinstate a code after it is in the field.

Full reference

The complete interactive definition, covering all endpoints and schemas, is published as OpenAPI:

api.vplatform.io/swagger

Codes, rules, actions and packages can also be managed through the VPlatform portal at portal.vplatform.io if you would rather click than curl while you are learning the model.

Want credentials?

Tell us what you are building. API access and SDK access are provided to approved partners.

Security and procurement questions are answered on the Trust Centre.