Discover events, tickets and passes
Choose a task: browse public events and tickets, read passes you own or are assigned, or check event access. A ticket definition describes what can be purchased. A purchased pass has an owner, who may assign someone else as the attendee.
Guest discovery
Member records and access
| Task | Operation |
|---|---|
| List events with owned passes | Owned events |
| Group owned/assigned ticket records | User tickets |
| List resource event passes, without owner/assignee restriction | Event passes |
| Read one owned pass | Pass detail |
| Decide assigned event access | Event access |
Example clients and synthetic values follow response conventions.
Owner member tasks
Use the owning member’s token and resource context.
| Task | Operation |
|---|---|
| Assign an unassigned owned pass | Assign an unassigned owned pass |
| Inspect unassign limitation | Inspect unassign limitation |
| Invite an attendee | Invite an attendee |
| Delete a pass invitation | Delete a pass invitation |
| Replace owner pass extra data | Replace owner pass extra data |
Recipient member tasks
Use the intended recipient’s active member token and resource context.
| Task | Operation |
|---|---|
| Validate a recipient invitation | Validate a recipient invitation |
| Activate a recipient invitation | Activate a recipient invitation |
Pass-token exchange
Use resource context and an existing pass authorization token; no member-token header is required.
| Task | Operation |
|---|---|
| Exchange a pass authorization token | Exchange a pass authorization token |
Resource and actor context
All these actions require a valid resource header with ti_events_system enabled. Guest discovery has guest ACL grants and no member guard. Member actions need an active user with existing token/resource context (configured Firebase handling where applicable). They use user ACL grants, not an event-administrator role. A prefix or list visibility does not establish narrower ownership. Operation-specific selection rules below determine which records are exposed. These GET handlers contain no explicit checkout, assignment, invitation or authorization writes; common credential initialization can have its own effects.
Read active resource events
GET /api/v1/ti-events
List active event records for the selected resource.
Before you call
Use the resource/actor context.
Selection checks resource_id and active=true only: no status, start/end window or schedule/quantity filter. Events are unpaginated; ordering unspecified.
Request
Bodyless; no action pagination/filter/order parameters are implemented. Result ordering is unspecified unless stated.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Select resource with enabled ticketing. |
Result
HTTP 200 items array of base events, [] if none.
Example: Show event 5001 as configured discovery data
A guest integration lists the selected resource’s active events without a member token. Event 5001 is discovery data; its active flag does not establish schedule availability or attendance. Other fields are defined in the linked projection.
curl "${WALLKIT_API_BASE}/api/v1/ti-events" \
-H "resource: ${RESOURCE_KEY}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/ti-events`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/ti-events",
headers={"resource": os.environ["RESOURCE_KEY"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"items": [
{
"id": 5001,
"title": "Example Session",
"active": true,
"photo": []
}
]
}
Consequential alternate
No active resource events gives HTTP 200 excerpt:
{
"items": []
}
Recovery
| HTTP status | API code / shape | Cause | Next action |
|---|---|---|---|
| 404 | resource_not_exists | Resource key missing/unresolved. | Check intended supplied public key. |
| 409 | ti_events_not_available; Not active for current Resource | Ticketing disabled in selected resource. | Ask integration owner to inspect ti_events_system. |
| 409 | ti_events | Caught query/serialization exception; message from exception. | Ask integration owner to inspect selected records/context; do not treat it as access or purchase success. |
Next task
Choose the returned event ID for ticket definitions; listing does not authorize attendance.
Read public ticket definitions for an event
GET /api/v1/ti-event/{id}/tickets
List active, nonprivate ticket definitions for one active resource event.
Before you call
Use the resource/actor context.
Event must match id/resource and active=true. Ticket selection checks active=true and is_private=false; no ticket status/window or positive-quantity filter. available counts all existing passes, clamped to zero. No capacity reservation or checkout occurs.
Request
Bodyless; no action pagination/filter/order parameters are implemented. Result ordering is unspecified unless stated.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Select resource with enabled ticketing. |
| id | path | required digits, integer-sanitized | Event ID from resource event list, not ticket/pass ID. |
Result
HTTP 200 items array of tickets with available, [] possible.
Example: Read ticket 6001 without reserving its capacity
A guest integration selects event 5001 and reads its active public ticket definitions. Ticket 6001 shows the current available count; listing it reserves no pass. Other fields are defined in the linked projection.
curl "${WALLKIT_API_BASE}/api/v1/ti-event/5001/tickets" \
-H "resource: ${RESOURCE_KEY}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/ti-event/5001/tickets`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/ti-event/5001/tickets",
headers={"resource": os.environ["RESOURCE_KEY"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"items": [
{
"id": 6001,
"ti_event_id": 5001,
"title": "Example Admission",
"quantity": 20,
"available": 5,
"price": 0,
"currency": "USD"
}
]
}
Consequential alternate
An inactive/missing/wrong-resource event gives HTTP 404 excerpt (other metadata omitted):
{
"error": "ti_events_not_found",
"error_description": "Not found Ti Event"
}
Recovery
| HTTP status | API code / shape | Cause | Next action |
|---|---|---|---|
| 404 | resource_not_exists | Resource key missing/unresolved. | Check intended supplied public key. |
| 409 | ti_events_not_available; Not active for current Resource | Ticketing disabled in selected resource. | Ask integration owner to inspect ti_events_system. |
| 409 | ti_event_tickets | Caught query/serialization exception; message from exception. | Ask integration owner to inspect selected records/context; do not treat it as access or purchase success. |
| 404 | ti_events_not_found; Not found Ti Event | Event missing/inactive/wrong resource. | Use intended active event ID/resource. |
Next task
Choose the intended ticket definition for the already documented User subscriptions and Pricing selection only when purchasing is intended; existing pass discovery is separate.
List events for which you own a pass
GET /api/v1/user/ti-events
Read events linked through passes owned by the current user.
Before you call
Use the resource/actor context.
Selection checks event.resource_id and pass.owner_id=current user, groups event ID; assigned-only attendees are not included. No event/ticket/pass active/status/date filter. Owning a pass is not event access; access uses assignment.
Request
Bodyless; no action pagination/filter/order parameters are implemented. Result ordering is unspecified unless stated.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Select resource with enabled ticketing. |
| token | header | required existing member context | Select active person; not a pass authorization token. |
Result
HTTP 200 items array of base events, [] possible.
Example: Discover owned event 5001 without claiming attendee access
Use purchaser 4001’s member context to find events with passes they own. Event 5001 can appear even when someone else is the assigned attendee. Other fields are defined in the linked projection.
curl "${WALLKIT_API_BASE}/api/v1/user/ti-events" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/ti-events`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/ti-events",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"items": [
{
"id": 5001,
"title": "Example Session"
}
]
}
Consequential alternate
No owned passes selects HTTP 200 excerpt:
{
"items": []
}
Recovery
| HTTP status | API code / shape | Cause | Next action |
|---|---|---|---|
| 404 | resource_not_exists | Resource key missing/unresolved. | Check intended supplied public key. |
| 409 | ti_events_not_available; Not active for current Resource | Ticketing disabled in selected resource. | Ask integration owner to inspect ti_events_system. |
| 409 | ti_events | Caught query/serialization exception; message from exception. | Ask integration owner to inspect selected records/context; do not treat it as access or purchase success. |
| 401 | auth_failed / auth_access_fail | Active member context not resolved. | Use intended existing member identity/context. |
Next task
Use user ticket groups to inspect owned/assigned records, or the separate event-access decision.
Group your owned or assigned ticket/pass records
GET /api/v1/user/ti-event-tickets
Read event→ticket→pass groups for an existing user-resource relationship.
Before you call
Use the resource/actor context.
Requires an existing UserResourceRelationship in addition to active user/resource initialization. Helper is typed to that relationship; absence can fail outside the caught Exception path, with no stable JSON/status contract. Selection expresses resource plus owner-or-assigned user predicates; no active/expiry/public filter. Predicate grouping is not an independent authorization guarantee. Inspect returned event context, and protect the raw ticket fields in your trusted application.
Request
Bodyless; no action pagination/filter/order parameters are implemented. Result ordering is unspecified unless stated.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Select resource with enabled ticketing. |
| token | header | required existing member context | Select active person; not a pass authorization token. |
Result
HTTP 200 top-level user ticket groups, with user_ti_events omitted when empty. Raw ticket serialization includes declared timestamps and can include deployment model columns. No paginator.
Example: Inspect ticket 6001 and pass 7001 under event 5001
Use an existing member-resource relationship to group owned or assigned passes. This excerpt links event 5001, ticket 6001 and pass 7001, with purchaser 4001 and assignee 4002 shown separately. Other fields are defined in the linked projection.
curl "${WALLKIT_API_BASE}/api/v1/user/ti-event-tickets" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/ti-event-tickets`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/ti-event-tickets",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"user_ti_events": [
{
"id": 5001,
"title": "Example Session",
"user_ti_event_tickets": [
{
"id": 6001,
"ti_event_id": 5001,
"title": "Example Admission",
"user_ti_event_ticket_passes": [
{
"id": 7001,
"owner_id": 4001,
"assign_id": 4002,
"extra": null
}
]
}
]
}
]
}
Consequential alternate
No qualifying groups gives HTTP 200 excerpt (optional debug metadata omitted):
{}
Recovery
| HTTP status | API code / shape | Cause | Next action |
|---|---|---|---|
| 404 | resource_not_exists | Resource key missing/unresolved. | Check intended supplied public key. |
| 409 | ti_events_not_available; Not active for current Resource | Ticketing disabled in selected resource. | Ask integration owner to inspect ti_events_system. |
| 409 | ti_events | Caught query/serialization exception; message from exception. | Ask integration owner to inspect selected records/context; do not treat it as access or purchase success. |
| 401 | auth_failed / auth_access_fail | Active member context not resolved. | Use intended existing member identity/context. |
| Unspecified | No stable JSON/status for missing typed user-resource relationship | Existing member lacks required relationship. | Ask integration owner to check account/resource relationship; do not treat malformed response as empty groups. |
Next task
Use owned pass detail only as the owning user; assignment alone is not its ownership check.
List passes for an event in the selected resource
GET /api/v1/user/ti-event/{id}/passes
Read every pass joined to the selected event/resource, without an owner or assignee predicate.
Before you call
Use the resource/actor context.
Despite the user prefix, this list does not restrict pass.owner_id/assign_id to the caller. Any active member passing common initialization can see the selected resource event’s base-pass IDs/extra/flags. Use only for intended trusted visibility; not a universal attendee-private list. Event need not pass active/date/status availability lookup. No separate missing-event error: no matching joined passes simply produces [].
Request
Bodyless; no action pagination/filter/order parameters are implemented. Result ordering is unspecified unless stated.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Select resource with enabled ticketing. |
| token | header | required existing member context | Select active person; not a pass authorization token. |
| id | path | required digits, integer-sanitized | Event ID, not ticket/pass ID. |
Result
HTTP 200 items array of base passes, [] possible. No ticket/event/user expansion or authorization token/link.
Example: Read event 5001’s base passes with the actual visibility limit
An active member lists base passes joined to event 5001 in the selected resource. The list is not restricted to that caller’s owned or assigned passes; use it only for the intended trusted visibility. Other fields are defined in the linked projection.
curl "${WALLKIT_API_BASE}/api/v1/user/ti-event/5001/passes" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/ti-event/5001/passes`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/ti-event/5001/passes",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"items": [
{
"id": 7001,
"owner_id": 4001,
"assign_id": 4002,
"extra": null
}
]
}
Consequential alternate
No joined passes gives HTTP 200 excerpt:
{
"items": []
}
Recovery
| HTTP status | API code / shape | Cause | Next action |
|---|---|---|---|
| 404 | resource_not_exists | Resource key missing/unresolved. | Check intended supplied public key. |
| 409 | ti_events_not_available; Not active for current Resource | Ticketing disabled in selected resource. | Ask integration owner to inspect ti_events_system. |
| 409 | ti_event_pass | Caught query/serialization exception; message from exception. | Ask integration owner to inspect selected records/context; do not treat it as access or purchase success. |
| 401 | auth_failed / auth_access_fail | Active member context not resolved. | Use intended existing member identity/context. |
Next task
Use intended pass ID with owned pass detail; list visibility does not establish owner action permission.
Read one pass owned by the current user
GET /api/v1/user/pass/{id}
Return an owned pass and its ticket/event as separate named fields.
Before you call
Use the resource/actor context.
Pass lookup checks id and owner_id=current user, not assign_id. It does not check selected resource against the pass event or active/date/status flags; valid/enabled header resource is an initialization prerequisite, not a proven pass-resource association. Missing ticket/event relations raise their dedicated 404 errors. No auth_link/token is added.
Request
Bodyless; no action pagination/filter/order parameters are implemented. Result ordering is unspecified unless stated.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Select resource with enabled ticketing. |
| token | header | required existing member context | Select active person; not a pass authorization token. |
| id | path | required digits, integer-sanitized | Purchased pass ID, not ticket definition or event ID. |
Result
HTTP 200 pass-detail wrapper: items is a named object, not an array.
Example: Resolve pass 7001 into its ticket 6001/event 5001
Use owner 4001’s member context to resolve pass 7001 into its separate ticket and event records. Assignee 4002 cannot use assignment alone to pass this ownership check. Other fields are defined in the linked projection.
curl "${WALLKIT_API_BASE}/api/v1/user/pass/7001" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/pass/7001`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/pass/7001",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"items": {
"ti_event_ticket_pass": {
"id": 7001,
"owner_id": 4001,
"assign_id": 4002
},
"ti_event_ticket": {
"id": 6001,
"ti_event_id": 5001
},
"ti_event": {
"id": 5001,
"title": "Example Session"
}
}
}
Consequential alternate
Pass absent or not owned by caller gives HTTP 404 excerpt (other metadata omitted):
{
"error": "ti_event_ticket_pass",
"error_description": "Ticket pass not found"
}
Recovery
| HTTP status | API code / shape | Cause | Next action |
|---|---|---|---|
| 404 | resource_not_exists | Resource key missing/unresolved. | Check intended supplied public key. |
| 409 | ti_events_not_available; Not active for current Resource | Ticketing disabled in selected resource. | Ask integration owner to inspect ti_events_system. |
| 409 | ti_event_tickets | Caught query/serialization exception; message from exception. | Ask integration owner to inspect selected records/context; do not treat it as access or purchase success. |
| 401 | auth_failed / auth_access_fail | Active member context not resolved. | Use intended existing member identity/context. |
| 404 | ti_event_ticket_pass / ti_event_ticket_pass_not_found / ti_event_ticket_not_found / ti_event_not_found | Owned pass or related ticket/event missing. | Use intended owned pass ID; ask owner to inspect missing relations. |
Next task
Use the event ID for an access decision as the intended assigned person; owner detail is not attendee authorization.
Decide access from a pass assignment
GET /api/v1/user/ti-event/{id}/access
Check whether current user is assigned a pass for one active resource event.
Before you call
Use the resource/actor context.
Event must match resource/id and active=true. The assignment lookup checks ticket.event ID and assign_id=current user only; it does not check pass.active, event schedule, ticket status or owned-pass purchase state. No assignment/access history write is present in this handler. This event decision is separate from content access.
Request
Bodyless; no action pagination/filter/order parameters are implemented. Result ordering is unspecified unless stated.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Select resource with enabled ticketing. |
| token | header | required existing member context | Select active person; not a pass authorization token. |
| id | path | required digits, integer-sanitized | Event ID in selected resource. |
Result
| Field | Type | Meaning |
|---|---|---|
ti_events_access | boolean | true with HTTP 200 when a pass assigned to the current user is found; false with HTTP 403 otherwise. |
Ordinary denial has no error envelope or API error code. No pass or user object is returned; shared optional response metadata may be present.
Example: Interpret assigned person 4002’s event-access decision
Use assigned person 4002’s member context to check event 5001. The Boolean reflects this action’s assignment checks; it is not a universal credential.
curl "${WALLKIT_API_BASE}/api/v1/user/ti-event/5001/access" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/ti-event/5001/access`, {
method: "GET", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/ti-event/5001/access",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="GET")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"ti_events_access": true
}
Consequential alternate
No pass assigned to current user gives HTTP 403. Synthetic excerpt; shared optional response metadata is omitted:
{
"ti_events_access": false
}
Recovery
| HTTP status | API code / shape | Cause | Next action |
|---|---|---|---|
| 404 | resource_not_exists | Resource key missing/unresolved. | Check intended supplied public key. |
| 409 | ti_events_not_available; Not active for current Resource | Ticketing disabled in selected resource. | Ask integration owner to inspect ti_events_system. |
| 409 | ti_event | Caught query/serialization exception; message from exception. | Ask integration owner to inspect selected records/context; do not treat it as access or purchase success. |
| 401 | auth_failed / auth_access_fail | Active member context not resolved. | Use intended existing member identity/context. |
| 404 | ti_events_not_found; Not found Ti Event | Event missing/inactive/wrong resource. | Use intended active event ID/resource. |
| 403 | ti_events_access:false | No matching assigned pass. | Handle denial; ownership alone is insufficient. |
Next task
Handle allow/deny in the application. For an article, still obtain its separate content-access decision.
Owner mutation context
Use resource/member context. These four actions resolve pass ID with owner_id=current user, reject any truthy assign_id, then require its event resource to strictly match the selected resource. An assignee alone cannot act as owner. Pass/event active flags, ticket status and schedule are not checked by this shared guard. Missing related ticket/event raises 404. A successful list/access decision is not an owner-action grant.
Conditional membership attachment
Direct assignment and invitation activation inspect ticket.extra.attach_subscription_id.
- If the setting is absent, the helper logs a skip. Otherwise the Pricing and Plan must exist in the selected resource.
- The first existing resource membership skips attachment only for an identical Plan ID or a strictly higher Plan priority. A different Plan at equal priority does not qualify for this skip. Membership expiry is not checked.
- When attachment proceeds, the shared helper can replace memberships, write history, stop/clear sponsorship relationships and attempt events or synchronization.
No price/active validation or provider charge occurs here. Nested transactions, unchecked saves and queues do not guarantee atomic rollback. A base pass response does not prove payment or content entitlement.
Assign an owned pass to an existing resource user
PUT /api/v1/user/pass/{id}/assign
Assign an unassigned pass to an existing person; ownership stays with the purchaser.
Before you call
Use the shared owner mutation guard.
Target person: assign_id must identify an existing user with a relationship to the selected resource. No other pass for the same ticket may already be assigned to that person. These checks do not require active or confirmed target state.
Changes: within a database transaction, the action sets assign_id, replaces authorization_token with a generated unique token, and attempts a pass save. Token generation can return null; the save result is not checked. Conditional membership attachment can also change account state.
Events and cache: assignment events are attempted, along with a token-generated event when the token is nonempty. Configured Mailchimp tags can trigger a synchronization queue attempt. Saving attempts to invalidate the current assignee’s cache prefix; this is not a full cache refresh. The transaction commits before returning.
A validation failure has no explicit rollback. A general failure attempts local rollback, which does not undo external queues or nested membership effects. Inspect saved state before repeating.
Request
Truthy JSON object required, Content-Type: application/json.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| id | path | required digits, integer-sanitized | Purchased pass ID, not event or ticket ID. |
| resource, token | headers | required existing context | Selected resource and active owning member. |
assign_id | JSON | required person ID with selected-resource relationship | Existing attendee user ID; duplicate same-ticket assignment rejected. |
Result
HTTP 200 JSON:
| Field | Type | Meaning |
|---|---|---|
| items | array with one base pass | The in-memory pass projection after attempted save. No authorization_token/auth_link or attendee object is added. |
Example: Assign pass 7001 to attendee 4002
As owner 4001, select attendee 4002 already registered in this resource. Excerpt omits other base-pass fields.
curl -X PUT "${WALLKIT_API_BASE}/api/v1/user/pass/7001/assign" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}" \
-H "Content-Type: application/json" \
--data-raw '{"assign_id": 4002}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/pass/7001/assign`, {
method: "PUT", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({"assign_id": 4002})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'assign_id': 4002}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/pass/7001/assign",
data=json.dumps(body).encode("utf-8"), headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"], "Content-Type": "application/json"}, method="PUT")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"items": [
{
"id": 7001,
"owner_id": 4001,
"assign_id": 4002
}
]
}
Consequential alternate
If pass 7001 is already assigned, HTTP 409 excerpt:
{
"error": "ti_event_ticket_pass",
"error_description": "Ticket pass is already assigned"
}
This does not replace an existing assignment. The generated credential is not returned in the success body.
Recovery
| HTTP | API code / shape | Cause | Recovery |
|---|---|---|---|
| 401 | auth_failed / auth_access_fail | Active owner context fails. | Resolve intended existing member context. |
| 404 | resource_not_exists | Resource missing/unresolved. | Check supplied resource key. |
| 409 | ti_events_not_available | Ticketing disabled. | Ask integration owner to inspect configuration. |
| 404 | ti_event_ticket_pass | Missing pass or caller is not owner. | Check pass ID and owning identity. |
| 404 | ti_event_ticket_not_found / ti_event_not_found | Related ticket/event missing. | Reconcile stored related records with owner. |
| 409 | ti_event_ticket_pass; Ticket pass is already assigned | Any truthy assign_id. | Inspect actual assignment; repeating does not bypass guard. |
| 409 | ti_event_resource; Incorrect Resource | Strict event-resource match fails. | Use the pass event’s intended resource. |
| 409 | ti_event_tickets | Caught general exception, message from exception. | Reconcile saved state and attempted events before repeating. |
| 406 | incorrect_data | Falsey/non-JSON body or target user missing. | Supply JSON and existing intended person ID. |
| 409 | invalid_assign_id | Missing/invalid resource relationship or duplicate ticket assignment. | Inspect target registration and existing same-ticket passes. |
Next task
Inspect owned pass detail and separately obtain an event-access decision as the assignee. Credential delivery follows the existing configured integration, not this response.
Inspect the unassign action’s shared-guard limitation
DELETE /api/v1/user/pass/{id}/assign
The intended removal of an existing assignment is blocked by the current shared guard.
Before you call
Use the shared owner mutation guard.
Assigned pass: the guard rejects it before clearing assign_id or authorization_token. A successful removal of an assigned attendee is not established by this source; the intended task’s primary success is N/A.
Already-unassigned pass: only this branch can reach the clearing step. It sets both fields to null, attempts an unchecked save and sends a removal event with null user_id. Tag-removal synchronization requires a nonempty prior assignee, which the guard normally excludes.
There is no enclosing transaction, explicit membership deletion or refund. With null assign_id, cache invalidation exits without clearing a former assignee’s prefix.
Request
Bodyless; no action JSON is consumed.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| id | path | required digits, integer-sanitized | Purchased pass ID, not event or ticket ID. |
| resource, token | headers | required existing context | Selected resource and active owning member. |
Result
Assigned pass: HTTP 409 error below. Already-unassigned branch only: HTTP 200 JSON:
| Field | Type | Meaning |
|---|---|---|
| items | array with one base pass | The in-memory pass projection after attempted save. No authorization_token/auth_link or attendee object is added. |
Example: Attempt to remove attendee 4002 from pass 7001
The request demonstrates the actual blocked task, not a working removal flow.
curl -X DELETE "${WALLKIT_API_BASE}/api/v1/user/pass/7001/assign" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/pass/7001/assign`, {
method: "DELETE", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/pass/7001/assign",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="DELETE")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 409 excerpt:
{
"error": "ti_event_ticket_pass",
"error_description": "Ticket pass is already assigned"
}
Consequential alternate
An already-unassigned pass can reach HTTP 200 excerpt:
{
"items": [
{
"id": 7001,
"owner_id": 4001,
"assign_id": null
}
]
}
This confirms neither removal of an assigned attendee nor deletion of attached memberships.
Recovery
| HTTP | API code / shape | Cause | Recovery |
|---|---|---|---|
| 401 | auth_failed / auth_access_fail | Active owner context fails. | Resolve intended existing member context. |
| 404 | resource_not_exists | Resource missing/unresolved. | Check supplied resource key. |
| 409 | ti_events_not_available | Ticketing disabled. | Ask integration owner to inspect configuration. |
| 404 | ti_event_ticket_pass | Missing pass or caller is not owner. | Check pass ID and owning identity. |
| 404 | ti_event_ticket_not_found / ti_event_not_found | Related ticket/event missing. | Reconcile stored related records with owner. |
| 409 | ti_event_ticket_pass; Ticket pass is already assigned | Any truthy assign_id. | Inspect actual assignment; repeating does not bypass guard. |
| 409 | ti_event_resource; Incorrect Resource | Strict event-resource match fails. | Use the pass event’s intended resource. |
| 409 | ti_event_tickets | Caught general exception, message from exception. | Reconcile saved state and attempted events before repeating. |
Next task
Ask the integration owner to reconcile the intended assignment change. Repeating this route cannot remove a truthy existing assignee under the documented guard.
Create an attendee invitation for an owned pass
POST /api/v1/user/pass/{id}/invite
Store an invitation and attempt a notification event; leave the pass unassigned.
Before you call
Use the shared owner mutation guard.
Email uses an Email validator (no separate presence validator), then email sanitization without explicit trim/lowercase normalization. A person with that stored email must not already have a pass assigned for the same ticket. Any existing invite for this pass blocks creation, whether the email matches or differs.
The entity generates a deterministic HMAC code from pass ID and sanitized email using the event resource secret, attempts unchecked invite save, then queues an event with code/email and owner context. No expiry window, assignee, authorization token, membership or checkout is created here. No enclosing transaction or guaranteed delivered email. Code generation is server-side; clients do not need the resource secret.
Request
Truthy JSON object required, Content-Type: application/json.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| id | path | required digits, integer-sanitized | Purchased pass ID, not event or ticket ID. |
| resource, token | headers | required existing context | Selected resource and active owning member. |
| JSON | attendee email, Email validator | Sanitized email; use the intended stored recipient address. |
Result
HTTP 200 empty JSON object {} apart from shared optional metadata. No result flag, invite ID/code, pass or delivery receipt is returned. The handler does not inspect the model save/delete boolean.
Example: Invite reader@example.com to pass 7001
Owner 4001 selects the recipient; retain pass ID separately from any code delivered through the existing invitation integration.
curl -X POST "${WALLKIT_API_BASE}/api/v1/user/pass/7001/invite" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}" \
-H "Content-Type: application/json" \
--data-raw '{"email": "reader@example.com"}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/pass/7001/invite`, {
method: "POST", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({"email": "reader@example.com"})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'email': 'reader@example.com'}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/pass/7001/invite",
data=json.dumps(body).encode("utf-8"), headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"], "Content-Type": "application/json"}, method="POST")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{}
Consequential alternate
An invite already exists for the same email: HTTP 409 excerpt:
{
"error": "ti_event_ticket_pass_invite_email",
"error_description": "Invitation already exist for the following e-mail address"
}
A different-email invite instead uses ti_event_ticket_pass_invite / Invitation already exist. A repeat is not a resend.
Recovery
| HTTP | API code / shape | Cause | Recovery |
|---|---|---|---|
| 401 | auth_failed / auth_access_fail | Active owner context fails. | Resolve intended existing member context. |
| 404 | resource_not_exists | Resource missing/unresolved. | Check supplied resource key. |
| 409 | ti_events_not_available | Ticketing disabled. | Ask integration owner to inspect configuration. |
| 404 | ti_event_ticket_pass | Missing pass or caller is not owner. | Check pass ID and owning identity. |
| 404 | ti_event_ticket_not_found / ti_event_not_found | Related ticket/event missing. | Reconcile stored related records with owner. |
| 409 | ti_event_ticket_pass; Ticket pass is already assigned | Any truthy assign_id. | Inspect actual assignment; repeating does not bypass guard. |
| 409 | ti_event_resource; Incorrect Resource | Strict event-resource match fails. | Use the pass event’s intended resource. |
| 409 | ti_event_tickets | Caught general exception, message from exception. | Reconcile saved state and attempted events before repeating. |
| 406 | incorrect_data | Falsey/non-JSON body. | Supply JSON object. |
| 409 | invalid_email | Email validation fails. | Use intended valid recipient address. |
| 409 | ti_event_ticket_pass_email | Same-ticket pass already assigned to a user with this email. | Inspect recipient assignment; do not duplicate it. |
| 409 | ti_event_ticket_pass_invite_email / ti_event_ticket_pass_invite | Existing invite or create exception. | Reconcile the invite and attempted notification before any repeat. |
Next task
Use the code supplied through the existing invitation delivery flow as the intended attendee. This response supplies no code and promises no delivery. Use delete invitation only for intended record removal.
Delete an invitation for an unassigned owned pass
DELETE /api/v1/user/pass/{id}/invite
Remove the invitation record for the selected pass; leave ownership and account records separate.
Before you call
Use the shared owner mutation guard.
After the shared guard, the entity finds an invite by pass ID, rejects a truthy activated flag, attempts unchecked delete and queues a deleted-invite event with old code/email/owner. An activated invite’s now-assigned pass can be rejected by the earlier assignment guard before the activated-invite check. No delivered-email recall, assignment removal, membership deletion, refund or authorization-token reset is performed. There is no enclosing transaction or checked-delete confirmation.
Request
Bodyless; no action JSON is consumed.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| id | path | required digits, integer-sanitized | Purchased pass ID, not event or ticket ID. |
| resource, token | headers | required existing context | Selected resource and active owning member. |
Result
HTTP 200 empty JSON object {} apart from shared optional metadata. No result flag, invite ID/code, pass or delivery receipt is returned. The handler does not inspect the model save/delete boolean.
Example: Remove pass 7001’s pending invitation
Owner 4001 removes a pending invitation for unassigned pass 7001. Use the pass ID; an invite ID/code is not the path value.
curl -X DELETE "${WALLKIT_API_BASE}/api/v1/user/pass/7001/invite" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}"
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/user/pass/7001/invite`, {
method: "DELETE", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN }
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/user/pass/7001/invite",
headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"]}, method="DELETE")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{}
Consequential alternate
No invitation exists for this pass: HTTP 404 excerpt:
{
"error": "ti_event_ticket_pass_invite",
"error_description": "Invitation not found"
}
An assigned pass fails the earlier HTTP 409 guard; an activated invite that reaches the entity fails with HTTP 409 Invitation is already activated.
Recovery
| HTTP | API code / shape | Cause | Recovery |
|---|---|---|---|
| 401 | auth_failed / auth_access_fail | Active owner context fails. | Resolve intended existing member context. |
| 404 | resource_not_exists | Resource missing/unresolved. | Check supplied resource key. |
| 409 | ti_events_not_available | Ticketing disabled. | Ask integration owner to inspect configuration. |
| 404 | ti_event_ticket_pass | Missing pass or caller is not owner. | Check pass ID and owning identity. |
| 404 | ti_event_ticket_not_found / ti_event_not_found | Related ticket/event missing. | Reconcile stored related records with owner. |
| 409 | ti_event_ticket_pass; Ticket pass is already assigned | Any truthy assign_id. | Inspect actual assignment; repeating does not bypass guard. |
| 409 | ti_event_resource; Incorrect Resource | Strict event-resource match fails. | Use the pass event’s intended resource. |
| 409 | ti_event_tickets | Caught general exception, message from exception. | Reconcile saved state and attempted events before repeating. |
| 404 | ti_event_ticket_pass_invite; Invitation not found | No selected pass invite. | Reconcile whether it was created/deleted; no resend implied. |
| 409 | ti_event_ticket_pass_invite | Activated invite or delete exception. | Inspect assignment/invite state before repeating. |
Next task
If a new intended recipient is needed, reconcile deletion before creating another invitation. No notification recall or account cleanup follows automatically.
Pass invitation recipient context
Both actions require resource and active member context, even without a user prefix in the route. Ticketing must be enabled. Supply the issuer-provided invitation code; it is different from a pass ID, member token or pass authorization token.
The code is string-sanitized without an explicit trim step and looked up exactly. The invitation must be unused, its pass unassigned and its event resource a strict match. The recipient need not own the pass.
The server recomputes the code using the current member’s stored email. Mismatch returns an error containing the intended recipient email. Invitation expiry, pass/event active flags and schedule are not checked. Generic invitation validation is a separate operation.
Validate a pass invitation as its recipient
POST /api/v1/ti-event/pass/invite-validation
Preview an existing code using the intended recipient’s active identity.
Before you call
Use the shared recipient checks. Validation does not save assignment, activate the invite, generate credentials or attach memberships. It previews current matching ticket/event context; it reserves nothing and does not guarantee later activation.
Request
Truthy JSON object required, Content-Type: application/json.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Selected resource with ticketing enabled. |
| token | header | required existing member context | Active intended recipient. |
| code | JSON | required nonempty string | Existing pass invitation code; exact lookup and current-email recomputation. |
Result
HTTP 200 JSON using recipient invitation context fields. No result flag, invite/pass object, auth_link or token is returned.
Example: Preview the invitation as reader@example.com
Use reader@example.com’s existing member context. INVITE_CODE_PLACEHOLDER stands for the issuer-provided code. Response excerpt omits other defined ticket/event fields.
curl -X POST "${WALLKIT_API_BASE}/api/v1/ti-event/pass/invite-validation" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}" \
-H "Content-Type: application/json" \
--data-raw '{"code": "INVITE_CODE_PLACEHOLDER"}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/ti-event/pass/invite-validation`, {
method: "POST", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({"code": "INVITE_CODE_PLACEHOLDER"})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'code': 'INVITE_CODE_PLACEHOLDER'}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/ti-event/pass/invite-validation",
data=json.dumps(body).encode("utf-8"), headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"], "Content-Type": "application/json"}, method="POST")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"ti_event_ticket": {
"id": 6001,
"ti_event_id": 5001
},
"ti_event": {
"id": 5001,
"title": "Example Session"
}
}
Consequential alternate
Already activated invitation: HTTP 409 excerpt:
{
"error": "ti_event_ticket_pass_invite",
"error_description": "Invitation has been already activated"
}
A preview cannot bypass this check. No universal replay or duplicate-success contract.
Recovery
| HTTP | API code / shape | Cause | Recovery |
|---|---|---|---|
| 404 | resource_not_exists | Missing/unresolved resource. | Check intended supplied resource key. |
| 409 | ti_events_not_available | Ticketing disabled. | Ask integration owner to inspect configuration. |
| 406 | incorrect_data | Falsey/non-JSON body. | Supply supported JSON object. |
| 401 | auth_failed / auth_access_fail | Active member context fails. | Resolve intended existing member identity. |
| 409 | invalid_code | Code missing/falsey. | Supply the existing invite code. |
| 404 | ti_event_ticket_pass_invite | Invitation absent. | Check issuer-provided code, not a pass/session token. |
| 409 | ti_event_ticket_pass_invite | Already activated or email mismatch. | Resolve intended recipient and inspect invite/pass state before repeating. |
| 404 | ti_event_ticket_pass / ti_event_ticket_not_found / ti_event_not_found | Related record absent. | Ask owner to reconcile pass/ticket/event. |
| 409 | ti_event_ticket_pass / ti_event_resource | Assigned pass or strict resource mismatch. | Inspect assignment and selected event resource. |
| 409 | ti_event_tickets | Caught general exception. | Check intended code, member email, resource and related ticket/event records; preview does not perform assignment/account writes. |
Next task
If acceptance is intended, separately activate the same invitation with the intended recipient’s member context; checks can change.
Activate a pass invitation as its recipient
POST /api/v1/ti-event/pass/invite-activation
Attempt assignment to the intended active member and mark invitation activated.
Before you call
Use the shared recipient checks. Activation checks the code again.
- The action starts a database transaction, sets the pass’s
assign_idto the current person and marks the invitation activated. Both save results are unchecked. - It does not generate an authorization token or clear the invitation code. Saving the pass attempts current-assignee cache invalidation.
- Conditional membership attachment can change account state. The action then attempts activation events and configured Mailchimp-tag synchronization before committing.
Validation failure attempts rollback; general failure has no explicit rollback. Nested membership transactions, unchecked saves and external events prevent an atomic or safe-repeat guarantee.
Request
Truthy JSON object required, Content-Type: application/json.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Selected resource with ticketing enabled. |
| token | header | required existing member context | Active intended recipient. |
| code | JSON | required nonempty string | Existing pass invitation code; exact lookup and current-email recomputation. |
Result
HTTP 200 JSON using recipient invitation context fields. No result flag, invite/pass object, auth_link or token is returned.
Example: Activate pass 7001’s invitation for reader@example.com
Use reader@example.com’s existing member context. INVITE_CODE_PLACEHOLDER stands for the issuer-provided code. Response excerpt omits other defined ticket/event fields.
curl -X POST "${WALLKIT_API_BASE}/api/v1/ti-event/pass/invite-activation" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}" \
-H "Content-Type: application/json" \
--data-raw '{"code": "INVITE_CODE_PLACEHOLDER"}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/ti-event/pass/invite-activation`, {
method: "POST", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({"code": "INVITE_CODE_PLACEHOLDER"})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'code': 'INVITE_CODE_PLACEHOLDER'}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/ti-event/pass/invite-activation",
data=json.dumps(body).encode("utf-8"), headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"], "Content-Type": "application/json"}, method="POST")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"ti_event_ticket": {
"id": 6001,
"ti_event_id": 5001
},
"ti_event": {
"id": 5001,
"title": "Example Session"
}
}
Consequential alternate
Already activated invitation: HTTP 409 excerpt:
{
"error": "ti_event_ticket_pass_invite",
"error_description": "Invitation has been already activated"
}
A preview cannot bypass this check. No universal replay or duplicate-success contract.
Recovery
| HTTP | API code / shape | Cause | Recovery |
|---|---|---|---|
| 404 | resource_not_exists | Missing/unresolved resource. | Check intended supplied resource key. |
| 409 | ti_events_not_available | Ticketing disabled. | Ask integration owner to inspect configuration. |
| 406 | incorrect_data | Falsey/non-JSON body. | Supply supported JSON object. |
| 401 | auth_failed / auth_access_fail | Active member context fails. | Resolve intended existing member identity. |
| 409 | invalid_code | Code missing/falsey. | Supply the existing invite code. |
| 404 | ti_event_ticket_pass_invite | Invitation absent. | Check issuer-provided code, not a pass/session token. |
| 409 | ti_event_ticket_pass_invite | Already activated or email mismatch; activation may also report assign failure. | Resolve intended recipient and inspect invite/pass state before repeating. |
| 404 | ti_event_ticket_pass / ti_event_ticket_not_found / ti_event_not_found | Related record absent. | Ask owner to reconcile pass/ticket/event. |
| 409 | ti_event_ticket_pass / ti_event_resource | Assigned pass or strict resource mismatch. | Inspect assignment and selected event resource. |
| 409 | ti_event_tickets | Caught general exception. | Reconcile local/account/queue effects before repeating. |
Next task
Obtain the separate event-access decision as the assignee. This action supplies no pass authorization token.
Exchange an existing pass authorization token
POST /api/v1/ti-event/ticket/pass/authorization
Create member session credentials for the pass’s assigned person using an existing pass authorization token.
Before you call
Supply resource context with ticketing enabled. This action has no member guard. The existing pass token must resolve a ticket/event in that resource, an assigned person and that person’s resource relationship. The action does not explicitly check pass/event active flags, ticket status or assigned-user active/confirmation state.
Time limit: the action rejects an event whose stored end date is earlier than 24 hours from now. That excludes the final 24 hours before the event’s stored end and earlier dates. It is not a 24-hour grace period after the event. Timestamp timezone and comparison normalization are unspecified.
Session writes: within a database transaction, authorization can update the resource lock or mark older sessions compromised under configured settings. It attempts new session and refresh-token saves, but this route returns only the member token; it omits refresh_token, expiry and session ID.
Firebase and history: the action can create an external Firebase user, save its relationship ID and request a custom token. Firebase exceptions are swallowed. Authorization history is saved without checking the result. The transaction commits before the authorization event is attempted.
A general failure attempts rollback even if it follows commit; that cannot undo external Firebase or event effects. The pass authorization token is retained. Neither one-time use nor successful reuse is guaranteed.
Request
Truthy JSON object required, Content-Type: application/json.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Selected resource with ticketing enabled. |
authorization_token | JSON | required nonempty string | Existing pass credential from configured issuer flow; not a member token or invite code. |
Result
HTTP 200 JSON:
| Field | Type / presence | Meaning |
|---|---|---|
| token | string | Newly generated Wallkit session token for assigned user; preserve as a credential. Persistence save is unchecked. |
firebase_custom_token | string, optional | External Firebase custom token if that nested flow succeeds. Not a Firebase ID token. |
No user/pass object, refresh token, expiry or content/event access decision is merged.
Example: Exchange the assigned pass credential
PASS_AUTHORIZATION_TOKEN_PLACEHOLDER is an existing issued credential. No member-token header is needed for this action. Synthetic returned token is a placeholder.
curl -X POST "${WALLKIT_API_BASE}/api/v1/ti-event/ticket/pass/authorization" \
-H "resource: ${RESOURCE_KEY}" \
-H "Content-Type: application/json" \
--data-raw '{"authorization_token": "PASS_AUTHORIZATION_TOKEN_PLACEHOLDER"}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/ti-event/ticket/pass/authorization`, {
method: "POST", headers: { "resource": process.env.RESOURCE_KEY, "Content-Type": "application/json" },
body: JSON.stringify({"authorization_token": "PASS_AUTHORIZATION_TOKEN_PLACEHOLDER"})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'authorization_token': 'PASS_AUTHORIZATION_TOKEN_PLACEHOLDER'}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/ti-event/ticket/pass/authorization",
data=json.dumps(body).encode("utf-8"), headers={"resource": os.environ["RESOURCE_KEY"], "Content-Type": "application/json"}, method="POST")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"token": "WALLKIT_SESSION_TOKEN_PLACEHOLDER"
}
Consequential alternate
Event ends earlier than 24 hours from now: HTTP 409 excerpt:
{
"error": "authorization_token_error",
"error_description": "TiEvent is no longer available"
}
A valid token can still fail this time/resource/assignment check. Optional Firebase failure can instead leave HTTP 200 with only token.
Recovery
| HTTP | API code / shape | Cause | Recovery |
|---|---|---|---|
| 404 | resource_not_exists | Missing/unresolved resource. | Check intended supplied resource key. |
| 409 | ti_events_not_available | Ticketing disabled. | Ask integration owner to inspect configuration. |
| 406 | incorrect_data | Falsey/non-JSON body. | Supply supported JSON object. |
| 409 | invalid_authorization_token | Missing/falsey credential. | Supply existing pass authorization token. |
| 409 | authorization_token_error | Token absent; event missing/wrong resource/too near end; no assigned user or resource registration. | Inspect intended pass/event/assignment context with issuer. |
| 409 | ti_event_tickets | General exception. | Reconcile session/history/Firebase state before repeating; creation may precede failure. |
Next task
Use returned token through member credential transport. Obtain event access or content access separately; identity creation is not either decision.
Replace extra data on an owned pass
PUT /api/v1/ti-event/ticket/pass/{id}/owner/extra
Replace the selected owned pass’s extra value after sanitization.
Before you call
Use active member/resource context with ticketing enabled. The pass is looked up by ID without checking its event’s resource. The current person must strictly match owner_id. Unlike assignment/invitation owner actions, this action does not require an unassigned pass. It does not check event/pass active flags or dates.
Replacement: extra is cast to an array. Keys receive string/trim filtering; nested JSON objects recurse. Other values receive string/trim filtering, so arrays, numbers and flags are not guaranteed to retain their original JSON types. The whole sanitized value replaces existing data rather than merging it.
The save result is unchecked. Sanitized data is logged, and saving attempts current-assignee cache invalidation. The action does not request assignment, token, membership or payment changes.
Request
Truthy JSON object required, Content-Type: application/json.
| Name | Location | Type / requirement | Meaning |
|---|---|---|---|
| resource | header | required public key | Selected resource with ticketing enabled. |
| token | header | required existing member context | Active intended owner. |
| id | path | required digits, integer-sanitized | Purchased pass ID. |
| extra | JSON | required present value, cast to array | Replacement data; prefer an object of text values/nested objects. Exact sanitization is not arbitrary JSON preservation. |
Result
HTTP 200 JSON:
| Field | Type | Meaning |
|---|---|---|
| item | base pass | Singular pass projection with replacement extra; no checked persistence confirmation. |
Example: Replace pass 7001’s attendee note
Owner 4001 replaces pass 7001’s attendee note, even when assigned to person 4002. Use text values to avoid assuming numeric/array preservation.
curl -X PUT "${WALLKIT_API_BASE}/api/v1/ti-event/ticket/pass/7001/owner/extra" \
-H "resource: ${RESOURCE_KEY}" \
-H "token: ${USER_TOKEN}" \
-H "Content-Type: application/json" \
--data-raw '{"extra": {"attendee_note": "Example access needs"}}'
const response = await fetch(`${process.env.WALLKIT_API_BASE}/api/v1/ti-event/ticket/pass/7001/owner/extra`, {
method: "PUT", headers: { "resource": process.env.RESOURCE_KEY, "token": process.env.USER_TOKEN, "Content-Type": "application/json" },
body: JSON.stringify({"extra": {"attendee_note": "Example access needs"}})
});
console.log(response.status, await response.json());
import os, json
from urllib.request import Request, urlopen
from urllib.error import HTTPError
body = {'extra': {'attendee_note': 'Example access needs'}}
request = Request(os.environ["WALLKIT_API_BASE"] + "/api/v1/ti-event/ticket/pass/7001/owner/extra",
data=json.dumps(body).encode("utf-8"), headers={"resource": os.environ["RESOURCE_KEY"], "token": os.environ["USER_TOKEN"], "Content-Type": "application/json"}, method="PUT")
try:
with urlopen(request) as response:
print(response.status, json.load(response))
except HTTPError as error:
print(error.code, json.load(error))
Synthetic HTTP 200 excerpt:
{
"item": {
"id": 7001,
"owner_id": 4001,
"assign_id": 4002,
"extra": {
"attendee_note": "Example access needs"
}
}
}
Consequential alternate
Caller is not strict owner: HTTP 403 excerpt:
{
"error": "user_not_auth",
"error_description": "User is not owner of ticket pass"
}
Being the assignee is insufficient, even if event access succeeds.
Recovery
| HTTP | API code / shape | Cause | Recovery |
|---|---|---|---|
| 404 | resource_not_exists | Missing/unresolved resource. | Check intended supplied resource key. |
| 409 | ti_events_not_available | Ticketing disabled. | Ask integration owner to inspect configuration. |
| 406 | incorrect_data | Falsey/non-JSON body. | Supply supported JSON object. |
| 401 | auth_failed / auth_access_fail | Active member context fails. | Resolve intended existing member identity. |
| 404 | ticket_pass_not_found | Pass ID absent. | Check intended purchased pass ID. |
| 403 | user_not_auth | Caller missing/not strict owner. | Use intended owner identity. |
| 409 | invalid_extra | Missing/falsey extra. | Supply supported replacement object. |
| 409 | ti_event_tickets | General exception. | Inspect saved/logged extra before repeating. |
Next task
Inspect owned pass detail for stored data. Treat event/content permission and credential exchange as separate tasks.