Events
Import offline event check-ins
Processes up to 1,000 array rows in order. Rows not marked present are skipped, then identity resolves by attendee ID, event ticket code or email. Valid original timestamps replace the check-in timestamp; invalid timestamps are ignored. A service validation error stops the request after earlier successful rows. Requires events_checkin or events_manage. Check-in mode must be enabled on the event.
POST
/
admin
/
events
/
{eventId}
/
check-ins
/
offline-import
Import offline event check-ins
curl --request POST \
--url https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"rows": [
{
"attendee_id": 42,
"ticket_code": "EVT-42-000123",
"email": "jane@example.org",
"status": "checked_in",
"checked_in_at": "2026-10-20T12:00:00Z"
}
]
}
'import requests
url = "https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import"
payload = { "rows": [
{
"attendee_id": 42,
"ticket_code": "EVT-42-000123",
"email": "jane@example.org",
"status": "checked_in",
"checked_in_at": "2026-10-20T12:00:00Z"
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
rows: [
{
attendee_id: 42,
ticket_code: 'EVT-42-000123',
email: 'jane@example.org',
status: 'checked_in',
checked_in_at: '2026-10-20T12:00:00Z'
}
]
})
};
fetch('https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'rows' => [
[
'attendee_id' => 42,
'ticket_code' => 'EVT-42-000123',
'email' => 'jane@example.org',
'status' => 'checked_in',
'checked_in_at' => '2026-10-20T12:00:00Z'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import"
payload := strings.NewReader("{\n \"rows\": [\n {\n \"attendee_id\": 42,\n \"ticket_code\": \"EVT-42-000123\",\n \"email\": \"jane@example.org\",\n \"status\": \"checked_in\",\n \"checked_in_at\": \"2026-10-20T12:00:00Z\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"rows\": [\n {\n \"attendee_id\": 42,\n \"ticket_code\": \"EVT-42-000123\",\n \"email\": \"jane@example.org\",\n \"status\": \"checked_in\",\n \"checked_in_at\": \"2026-10-20T12:00:00Z\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"rows\": [\n {\n \"attendee_id\": 42,\n \"ticket_code\": \"EVT-42-000123\",\n \"email\": \"jane@example.org\",\n \"status\": \"checked_in\",\n \"checked_in_at\": \"2026-10-20T12:00:00Z\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": [
{
"row": 0,
"status": "skipped",
"message": "No attendee matched this offline row.",
"attendee": {
"id": 42,
"order_id": 42,
"order_number": "Example",
"name": "Example",
"first_name": "Example",
"last_name": "Example",
"email": "Example",
"phone": "Example",
"status": "Example",
"ticket_type": "Example",
"table": "Example",
"registration_source": "Example",
"registration_group": "Example",
"checked_in_at": "2026-10-20T12:00:00Z",
"details_complete": false,
"is_walk_in": false
}
}
]
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}Authorizations
bearerAuthapiKeyAuth
Passport bearer token authentication for legacy admin sessions.
Path Parameters
Record ID in the authenticated organization.
Example:
42
Body
application/json
Required array length:
1 - 1000 elementsShow child attributes
Show child attributes
Response
Import offline event check-ins completed.
Show child attributes
Show child attributes
⌘I
Import offline event check-ins
curl --request POST \
--url https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"rows": [
{
"attendee_id": 42,
"ticket_code": "EVT-42-000123",
"email": "jane@example.org",
"status": "checked_in",
"checked_in_at": "2026-10-20T12:00:00Z"
}
]
}
'import requests
url = "https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import"
payload = { "rows": [
{
"attendee_id": 42,
"ticket_code": "EVT-42-000123",
"email": "jane@example.org",
"status": "checked_in",
"checked_in_at": "2026-10-20T12:00:00Z"
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
rows: [
{
attendee_id: 42,
ticket_code: 'EVT-42-000123',
email: 'jane@example.org',
status: 'checked_in',
checked_in_at: '2026-10-20T12:00:00Z'
}
]
})
};
fetch('https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'rows' => [
[
'attendee_id' => 42,
'ticket_code' => 'EVT-42-000123',
'email' => 'jane@example.org',
'status' => 'checked_in',
'checked_in_at' => '2026-10-20T12:00:00Z'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import"
payload := strings.NewReader("{\n \"rows\": [\n {\n \"attendee_id\": 42,\n \"ticket_code\": \"EVT-42-000123\",\n \"email\": \"jane@example.org\",\n \"status\": \"checked_in\",\n \"checked_in_at\": \"2026-10-20T12:00:00Z\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"rows\": [\n {\n \"attendee_id\": 42,\n \"ticket_code\": \"EVT-42-000123\",\n \"email\": \"jane@example.org\",\n \"status\": \"checked_in\",\n \"checked_in_at\": \"2026-10-20T12:00:00Z\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.gratona.com/v1/admin/events/{eventId}/check-ins/offline-import")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"rows\": [\n {\n \"attendee_id\": 42,\n \"ticket_code\": \"EVT-42-000123\",\n \"email\": \"jane@example.org\",\n \"status\": \"checked_in\",\n \"checked_in_at\": \"2026-10-20T12:00:00Z\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": [
{
"row": 0,
"status": "skipped",
"message": "No attendee matched this offline row.",
"attendee": {
"id": 42,
"order_id": 42,
"order_number": "Example",
"name": "Example",
"first_name": "Example",
"last_name": "Example",
"email": "Example",
"phone": "Example",
"status": "Example",
"ticket_type": "Example",
"table": "Example",
"registration_source": "Example",
"registration_group": "Example",
"checked_in_at": "2026-10-20T12:00:00Z",
"details_complete": false,
"is_walk_in": false
}
}
]
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Something went wrong. Please try again.",
"status": "error",
"error": "invalid_request",
"code": "DONOR_NOT_FOUND"
}{
"message": "Not Found",
"status": "error"
}{
"errors": {},
"status": "error",
"message": "The given data was invalid."
}