Skip to content

API quick start

The order to build in, then the same thing as commands you can paste.

  1. Store the key and secret in a server-side secret manager — see credentials.
  2. Fetch the reference lists — job types, priorities, countries, states — and keep a map of name to ID.
  3. Look up the customer before creating anything.
  4. For a known customer, look up their sites and contacts.
  5. Create the job with those three IDs — or create a request if the customer is new.
  6. Send a unique Idempotency-Key on every create.
  7. Persist your external_id, the returned IDs and the request_id.
  8. Retry only on 429, with the same key, after Retry-After. Nothing else retries automatically.

Remember there is no test environment. Everything below runs against your live account, which is why the examples prefix their external IDs with TEST-.

Terminal window
AUTH="Authorization: Bearer YOUR_API_KEY:YOUR_API_SECRET"
BASE="https://{sub_domain}.eyeontask.com/en/eotServices/api/v1"

The IDs used below — 101, 22, 12, 501, 701, 901 — are placeholders. Use the ones your own calls return.

Terminal window
curl -s "$BASE/job-types" \
-H "$AUTH" \
-H "Accept: application/json"
curl -s "$BASE/priorities" \
-H "$AUTH" \
-H "Accept: application/json"
curl -s "$BASE/countries" \
-H "$AUTH" \
-H "Accept: application/json"
curl -s "$BASE/states?country_id=101" \
-H "$AUTH" \
-H "Accept: application/json"

2. Find a customer, then its sites and contacts

Section titled “2. Find a customer, then its sites and contacts”
Terminal window
curl -s "$BASE/customers?email=customer@example.com" \
-H "$AUTH" \
-H "Accept: application/json"
curl -s "$BASE/customers/501/sites" \
-H "$AUTH" \
-H "Accept: application/json"
curl -s "$BASE/customers/501/contacts" \
-H "$AUTH" \
-H "Accept: application/json"

Check total before using a result — more than one match is not a result.

Terminal window
curl -s -X POST "$BASE/jobs" \
-H "$AUTH" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: crm-job-2026-000123" \
-d '{
"external_id": "TEST-CRM-JOB-10001",
"description": "Annual AC maintenance",
"priority_id": 2,
"customer": {
"id": 501,
"site": { "id": 701 },
"contact": { "id": 901 }
},
"job_types": [
{ "job_type_id": 12 }
],
"schedule": {
"start_at": "2026-09-10T10:00:00+05:30"
}
}'

No end_at, so the job is an hour long. It arrives Not Dispatched.

Terminal window
curl -s -X POST "$BASE/requests" \
-H "$AUTH" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: crm-req-2026-000456" \
-d '{
"external_id": "TEST-CRM-REQUEST-10002",
"description": "New customer enquiry",
"source": "CRM",
"customer": {
"name": "New Customer Ltd",
"site": {
"address": "10 Main Street",
"city": "Mumbai",
"country_id": 101,
"state_id": 22
},
"contact": {
"name": "Anita Sharma",
"email": "anita@example.com"
}
},
"job_types": []
}'

No customer, site or contact ID anywhere — that is what makes it Mode B.

Send step 3 again, unchanged, with the same Idempotency-Key. The answer is 200 carrying the original response, and no second job exists.

That is the behaviour to lean on when a call times out and you do not know whether it landed: retry it exactly, rather than checking first — because there is no endpoint to check with.

The TEST- prefix is what makes this possible. Those jobs and requests are real ones in your live account, so find them in the app and delete or cancel them once you are done — see editing and deleting a request and job actions.