Build a connector

Get exhibitor data in.

Bring your exhibitor roster into Standwyse from wherever it lives today — a spreadsheet, your CRM, or your customer data platform. Two ways in, both writing through the same idempotent path so they never duplicate rows.

Two ways in

CSV import — for a one-off or occasional load, export your roster as CSV and upload it from the organiser Exhibitors page. Map your columns, preview, and commit. Re-uploading an updated file updates the same accounts rather than creating duplicates.

Ingestion API — for an automated, repeatable sync from your own systems. POST a batch of exhibitors to /api/ingest/exhibitors. This is the same endpoint a Zapier app or a partner connector builds against — the full machine-readable contract is the interactive API reference.

Authentication

The API authenticates with a per-tenant API key. Generate one from the organiser Exhibitors page — it is shown once at creation, so copy it somewhere safe. Send it as a bearer token on every request:

Authorization header
Authorization: Bearer swk_live_your_key_here

A key is scoped to the organisation that created it, so it can only ever write into that organisation’s events. Revoke a key at any time from the same page; a revoked key immediately returns 401.

Idempotency — upsert by external_id

Every exhibitor row carries an external_id: your system’s stable id for that company (a CRM record id, for example). Standwyse keys on it, so sending the same external_id again updates the existing account instead of creating a second one. That makes the endpoint safe to retry and safe to run on a schedule — a nightly full-roster push converges rather than piling up duplicates.

Send a batch

  1. Generate an API key
    On the organiser Exhibitors page, create an ingestion key and copy it.
  2. POST your exhibitors
    Send a batch of up to 1000 rows to /api/ingest/exhibitors for one event_slug.
  3. Read the result
    applied tells you how many rows were saved; failed lists any rows that were rejected, by line and field.
curl
curl -X POST https://standwyse.com/api/ingest/exhibitors \
  -H "Authorization: Bearer swk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "event_slug": "aurora-tech-expo",
    "exhibitors": [
      {
        "external_id": "crm-8842",
        "account_name": "Helix Robotics Ltd",
        "contact_email": "ops@helixrobotics.example.com",
        "reference_code": "EX-204",
        "package_name": "Premium 6x4"
      }
    ]
  }'
JavaScript (fetch)
const res = await fetch("https://standwyse.com/api/ingest/exhibitors", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.STANDWYSE_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    event_slug: "aurora-tech-expo",
    exhibitors: [
      {
        external_id: "crm-8842",
        account_name: "Helix Robotics Ltd",
        contact_email: "ops@helixrobotics.example.com"
      }
    ]
  })
});

const result = await res.json();
// { "applied": 1, "inserted": 1, "updated": 0, "failed": [] }

Response & partial failures

Good rows always apply, even when others fail. The response reports how many rows were saved and lists every rejected row by its 1-based position in the batch — nothing is silently dropped.

200 — partial success
{
  "applied": 2,
  "inserted": 1,
  "updated": 1,
  "failed": [
    { "line": 3, "field": "contact_email", "message": "Invalid email" }
  ]
}

applied is inserted + updated. Each entry in failed names the offending line, field, and a human-readable message.

Errors

Whole-request problems return a single error envelope with the matching HTTP status:

error shape
{ "error": "Invalid or revoked API key." }
  • 400 — body isn’t valid JSON, or fails top-level validation
  • 401 — missing, invalid, or revoked API key
  • 404 — no event with that slug in this key’s organisation
  • 413 — request body exceeds the size cap
  • 429 — rate limit exceeded (see the Retry-After header)

CSV column spec

The importer accepts any column order and maps common header names automatically. The downloadable template on the Exhibitors page uses these columns:

  • external_id — required. Your stable id; the idempotency key.
  • account_name — required. The exhibiting company’s name.
  • contact_email — optional. Primary contact email.
  • reference_code — optional. Your booking/reference code.
  • package_name — optional. Stand or sponsorship package.
  • status — optional. Defaults to active.