MJX EventsDocs

Partner API — run your guests and tickets from your own system

The MJX Events Partner API. Your own dashboard creates events and priced tickets, approves guests, sends tickets (paid to you, or with an MJX pay link) and gets webhooks for payments and check-ins.

DeveloperOrganizer9 min read · Updated 2026-11-02 View as Markdown

Run everything from your own dashboard: MJX Events works in the background. Your system creates the event and its tickets (free or with a price), approves guests, and MJX sends each ticket on WhatsApp and email with its QR, in the event's ticket design. Webhooks tell your system what happened (paid, checked in, a new request). The gate scanner, Attendees and payouts work as for any MJX ticket.

#How it fits together

  1. Your dashboard creates the event and its tickets, approves guests and sends passes — each action is one API call. Requests guests make on MJX (event page, request page, your form's link) reach it too.
An example company's dashboard: guests waiting, pay links out, tickets sent and checked in; on the right, each API call and webhook
Your dashboard, with the API calls and webhooks behind it
  1. The guest's phone gets the QR ticket on WhatsApp and email — or first a pay link, when MJX collects the money. Paying updates your dashboard by itself (webhook ticket.sent).
The guest's phone: the WhatsApp pay link, then the confirmed booking and the QR ticket
The guest's phone
  1. At the gate your staff use the MJX Events scanner app. Each scan sends ticket.checked_in to your system, so the guest shows as checked in on your dashboard with no polling — even scans made offline, once the phone syncs.
The MJX scanner says Welcome, admits 2; the same moment the webhook ticket.checked_in reaches the dashboard
Gate scan → your dashboard

Base URL: https://event.mjxtechnologies.com/api/partner/v1

#Before you start

  • MJX switches the Partner API on for your account.
  • On event.mjxtechnologies.com › account menu › Developers (API): make a key. It is shown once; keep it on your server only. A test key (mjx_test_…) checks every call and answers, but makes and sends nothing.
  • Send the key in the X-Api-Key header. Bodies and answers are JSON. Up to 120 calls a minute per key.

#Events: made on the website, or by your system

On the website: create and publish the event as usual (ticket design, venue, gate scanner). Its code (e.g. K7M2PQ) is under Developers.

By your system: POST /events makes a live event with a guests-only pass. Give it your own ref: the same ref again returns that event, never a second one.

POST /api/partner/v1/events
X-Api-Key: mjx_live_xxxxxxxx

{ "ref": "EVT-2027-ANNUAL", "name": "Annual Meet 2027",
  "startAt": "2027-01-03 19:00", "endAt": "2027-01-03 23:00",
  "venue": "Hindustan Club", "city": "Bhagalpur",
  "passes": 300, "maxPeople": 2 }

→ 201 { "event": { "code": "K7M2PQ", "ref": "EVT-2027-ANNUAL", "status": "LIVE",
                   "page": "https://event.mjxtechnologies.com/e/…",
                   "passes": { "name": "Guest pass", "total": 300, "left": 300 } } }

With your own ticket prices: send types instead of passes. Price is in rupees (0 = free); persons = how many people one ticket admits. Tickets made through the API are invitation tickets: requested and approved, never in the event page's cart. A price needs paid invitation tickets switched on for your account.

POST /api/partner/v1/events
X-Api-Key: mjx_live_xxxxxxxx

{ "ref": "EVT-2027-GALA", "name": "Annual Gala 2027", "startAt": "2027-01-03 19:00", "venue": "Hindustan Club", "city": "Bhagalpur",
  "types": [ { "name": "Guest pass", "price": 0, "quantity": 300 },
             { "name": "VIP couple", "price": 1000, "quantity": 40, "persons": 2, "description": "Front rows, dinner" } ] }

→ 201 { "event": { "code": "K7M2PQ", …, "types": [ { "id": "…", "name": "Guest pass", "price": 0, "quantity": 300, "left": 300, "persons": 1 },
                                                  { "id": "…", "name": "VIP couple", "price": 1000, "quantity": 40, "left": 40, "persons": 2 } ] } }

Add a ticket later: POST /events/K7M2PQ/types with { "name": "Staff", "price": 0, "quantity": 20 }.

Times without a zone are India time; ISO dates with a zone work too. GET /events lists your events with codes, their tickets (types) and the free pass a call gets when it names no ticket (passes). The ticket design, the gate scanner PIN and the rest are set on the website.

#Send a guest's pass (the main call)

POST /api/partner/v1/tickets
X-Api-Key: mjx_live_xxxxxxxx

{ "event": "K7M2PQ",
  "ref": "REQ-20417",
  "name": "Asha Rao",
  "phone": "9876543210",
  "email": "asha.rao@gmail.com",
  "address": "Naya Bazar, Bhagalpur",
  "people": 2 }

→ 201 { "ticket": { "ref": "REQ-20417", "status": "SENT", "people": 2,
                    "event": { "code": "K7M2PQ", "name": "Annual Meet 2027" },
                    "tickets": [ { "code": "8F2KQ7", "status": "VALID" }, { "code": "R4T8WX", "status": "VALID" } ],
                    "sentTo": { "whatsapp": true, "email": true },
                    "link": "https://event.mjxtechnologies.com/orders/…", "pdf": "…" } }
  • ref is your own id for the guest. Sending the same ref again returns the pass made before (200), so retries never make two.
  • phone or email is needed (both is best). Each person gets their own QR.
  • event can also be the event's details instead of a code: { "ref": "EVT-2027-ANNUAL", "name": "…", "startAt": "…", "venue": "…", "city": "…", "passes": 300 }. MJX finds the event by your ref, or makes it the first time.
  • Without ticketType, the pass is the event's free invitation ticket (the one GET /events shows under passes). An event whose invitation tickets all have a price answers 409: add a free one on the website, or name a free ticket type.
  • Optional: ticketType (the ticket's name), extra (your own fields, kept with the guest).

#Tickets with a price: payment

A ticket with a price needs payment:

paymentUse it whenWhat happens
"paid"The guest already paid you (your own form or gateway, cash, UPI)The ticket is sent at once — no MJX link. Recorded at the ticket's price as paid to you outside MJX: not in MJX payouts, shown under Insights. MJX's free-ticket fee applies per ticket (from your free-ticket credits; with none, the call answers 402).
"link"MJX should collectThe guest gets a pay link on WhatsApp and email (valid 48 hours); the ticket comes when they pay. Status PAY with payUrl and payBy; then SENT, or EXPIRED if not paid. Paid out like any online sale.
{ "event": "K7M2PQ", "ref": "REQ-20418", "name": "Rahul Verma", "phone": "9988776655",
  "ticketType": "VIP couple", "payment": "paid" }

The guest's ticket shows the ticket's name (e.g. "VIP couple") — never "Free", never a price.

#Status, lists, resend, cancel

GET  /api/partner/v1/tickets/REQ-20417          → { "ticket": { "status": …, "payment": "free" | "paid" | "online" | "link", "amount": 1000, "tickets": [ … ], … } }
GET  /api/partner/v1/tickets?event=K7M2PQ&status=SENT&page=1   → { "total": 42, "page": 1, "pages": 1, "tickets": [ … ] }
POST /api/partner/v1/tickets/REQ-20417/resend   → the tickets again on WhatsApp and email (3 an hour)
POST /api/partner/v1/tickets/REQ-20417/cancel   → the QR stops working at the gate; the place goes back to the event

Statuses: WAITING (for approval) · PAY (pay link out) · SENT · CHECKED_IN · DECLINED · EXPIRED (pay link not paid in time) · CANCELLED.

Guests can also ask on MJX: the event page's Request button, MJX's request page, or a form that posts to the event's request link. Approve them from your dashboard:

GET  /api/partner/v1/requests?event=K7M2PQ                  → { "requests": [ { "id": "cm…", "name": "Imran Khan", "status": "WAITING", "ticketType": { "name": "VIP couple", "price": 1000 }, … } ] }
POST /api/partner/v1/requests/cm…/approve   { "payment": "paid" }   → ticket sent (free tickets need no body)
POST /api/partner/v1/requests/cm…/approve   { "payment": "link" }   → pay link sent
POST /api/partner/v1/requests/cm…/decline                   → the guest is told; one paid through MJX first is refunded in full

They also show under the event's Requests on event.mjxtechnologies.com and in the app, with the same choice: Approve · pay link or Approve · paid to you.

#Webhooks

Under Developers (API), open Webhook on a key and add your address (https). MJX then calls it with JSON for each of these, with the same ticket body as the API:

typeWhen
request.createdA guest asked on MJX (event page, request page, your form's link)
payment.link_sentA pay link went out
ticket.sentA ticket was sent (approved, paid to you, or the guest paid the link)
payment.expiredA pay link ran out; the place is free again
ticket.checked_inScanned in at the gate
ticket.cancelledCancelled through the API
request.declinedDeclined
{ "id": "cm…", "type": "ticket.sent", "createdAt": "2027-01-02T10:15:00.000Z",
  "data": { "ticket": { "id": "cm…", "ref": "REQ-20418", "status": "SENT", "payment": "online", "amount": 1000, … } } }

Every call carries X-MJX-Event, X-MJX-Delivery, X-MJX-Timestamp and X-MJX-Signature: sha256=… — an HMAC-SHA256 of "<timestamp>.<body>" with the key's webhook secret. Check it, then answer 2xx within 10 seconds. Not answered: MJX tries again after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 24 hours. Send a test on the Developers page sends a ping.

// Node.js (Express): check the signature
const crypto = require("crypto");
app.post("/mjx-webhook", express.raw({ type: "application/json" }), (req, res) => {
  const ts = req.get("X-MJX-Timestamp");
  const want = "sha256=" + crypto.createHmac("sha256", process.env.MJX_WEBHOOK_SECRET).update(`${ts}.${req.body}`).digest("hex");
  if (req.get("X-MJX-Signature") !== want) return res.sendStatus(401);
  const { type, data } = JSON.parse(req.body);
  // update your dashboard with data.ticket …
  res.sendStatus(200);
});

#Examples

#curl (quick test)

Under Developers (API) these are ready to copy, with your key and an event code filled in. With a test key nothing is made or sent.

# Check the key: your events and their codes
curl https://event.mjxtechnologies.com/api/partner/v1/events \
  -H "X-Api-Key: YOUR_KEY"

# Send a guest's pass
curl -X POST https://event.mjxtechnologies.com/api/partner/v1/tickets \
  -H "X-Api-Key: YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event":"K7M2PQ","ref":"test-1","name":"Test Guest","email":"you@example.com"}'

# Its status (after a live key sent it; a test key makes nothing to look up)
curl https://event.mjxtechnologies.com/api/partner/v1/tickets/test-1 \
  -H "X-Api-Key: YOUR_KEY"

#PHP

$ch = curl_init("https://event.mjxtechnologies.com/api/partner/v1/tickets");
curl_setopt_array($ch, [
  CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["X-Api-Key: " . getenv("MJX_KEY"), "Content-Type: application/json"],
  CURLOPT_POSTFIELDS => json_encode(["event" => "K7M2PQ", "ref" => $req->id, "name" => $req->name,
                                     "phone" => $req->phone, "email" => $req->email, "people" => 2]),
]);
$res = json_decode(curl_exec($ch), true);

#Node.js

const res = await fetch("https://event.mjxtechnologies.com/api/partner/v1/tickets", {
  method: "POST",
  headers: { "X-Api-Key": process.env.MJX_KEY, "Content-Type": "application/json" },
  body: JSON.stringify({ event: "K7M2PQ", ref: req.id, name: req.name, phone: req.phone, email: req.email, people: 2 }),
});
const { ticket, error } = await res.json();

#Python

import os, requests
r = requests.post("https://event.mjxtechnologies.com/api/partner/v1/tickets", headers={"X-Api-Key": os.environ["MJX_KEY"]},
    json={"event": "K7M2PQ", "ref": req.id, "name": req.name, "phone": req.phone, "email": req.email, "people": 2})
ticket = r.json()["ticket"]

#Answers

CodeMeaning
201Made (and sent)
200The same ref again: what was made before
401Key missing, wrong or revoked
403The Partner API (or, for a price, paid invitation tickets) is not switched on for the account
402Not enough free-ticket credits for MJX's fee on a ticket paid to you: buy credits, then send the same ref again
404No such event or ref on your account
409No passes left, or the event is not live
422A field is missing or wrong: the error says which
429Too many calls: wait a minute
500Our side: try again with the same ref

Every error is { "error": "…" } in plain words.

  • Live demo — an example company's dashboard running on this API
  • Invitation tickets — guests who request through your event page or your own form instead

#Questions people ask

How do I get an API key?

MJX switches the Partner API on for your account. Then on event.mjxtechnologies.com open the account menu › Developers (API) and make a key. It is shown once.

Can I test without sending real passes?

Yes. A test key (mjx_test_…) checks every call and answers like a live key, but makes and sends nothing.

What if my call times out and I send it again?

Send the same ref. MJX returns the pass made the first time (200), so retries never make two.

Can the API issue paid tickets?

Yes, with paid invitation tickets switched on for your account. Send "payment": "paid" when the guest already paid you (the ticket goes at once, no MJX link), or "link" for MJX to send a pay link.

How does my system know a guest paid or was checked in?

Add a webhook address under Developers (API). MJX calls it, signed, for new requests, pay links, payments, expired links, check-ins, cancellations and declines.