API quick start
The order to build in, then the same thing as commands you can paste.
The sequence
Section titled “The sequence”- Store the key and secret in a server-side secret manager — see credentials.
- Fetch the reference lists — job types, priorities, countries, states — and keep a map of name to ID.
- Look up the customer before creating anything.
- For a known customer, look up their sites and contacts.
- Create the job with those three IDs — or create a request if the customer is new.
- Send a unique Idempotency-Key on every create.
- Persist your
external_id, the returned IDs and therequest_id. - 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-.
Common variables
Section titled “Common variables”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.
1. Reference data
Section titled “1. Reference data”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”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.
3. Create a job for an existing customer
Section titled “3. Create a job for an existing customer”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.
4. Create a request for a new customer
Section titled “4. Create a request for a new customer”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.
5. Retrying safely
Section titled “5. Retrying safely”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.
Cleaning up afterwards
Section titled “Cleaning up afterwards”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.