> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs.hellotracks.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create an ETA session

> Creates a live ETA page (https://eta.page/...) for a job's recipient. If the job already has an active session (not revoked, not expired), that one is returned as it is and the body is ignored. Recipient fields default to the job's contact. Expiry defaults to 30 days, at most 90 days. Status 200, not 201. Workers are refused with 403 (code permission_denied); an unknown job gives 400.



## OpenAPI

````yaml v1/openapi.json POST /eta/sessions
openapi: 3.1.0
info:
  title: Hellotracks REST API
  version: '1'
  description: >-
    Plain REST resources over HTTPS, for tools, automations and services. The ht
    command line is built on it.
  contact:
    email: api@hellotracks.com
servers:
  - url: https://api.hellotracks.com/v1
security:
  - ApiKey: []
tags:
  - name: Sign-up and sign-in
    description: >-
      Create a company or get an API key by an emailed code, without a key; and
      check which account a key belongs to.
  - name: Company
    description: The company the API key belongs to, with its settings and teams.
  - name: Members
    description: 'The people in the company: admins, operators and workers.'
  - name: API keys
    description: 'The company''s API keys: list, create, revoke and delete.'
  - name: Jobs
    description: 'Jobs: work at a location on a date, assigned to a member.'
  - name: Places
    description: 'Places: customer sites and other saved locations with a check-in radius.'
  - name: Zones
    description: 'Zones: the company''s geofences.'
  - name: Routing
    description: Route optimization for one member's day.
  - name: ETA pages
    description: >-
      Live ETA pages (eta.page links) that show a job's recipient when the
      worker arrives.
  - name: Maps
    description: Rendered maps as GeoJSON, and public map share links.
  - name: Timesheets
    description: Clock-in and clock-out entries of members, with totals, and editing them.
  - name: Forms
    description: >-
      Form templates, submitted forms, attachments for file and image fields,
      and forms linked to places and jobs.
  - name: Alerts
    description: >-
      Alert rules (configs) that watch members, places and zones, and the alerts
      (instances) they raised.
  - name: Reports
    description: >-
      Reports: the newer reporting API (catalog, preview, run, saved) and the
      older one (types, generate, jobs, uploads, recurring).
  - name: Webhooks
    description: URLs Hellotracks calls when jobs, check-ins, clock-ins or alerts happen.
paths:
  /eta/sessions:
    post:
      tags:
        - ETA pages
      summary: Create an ETA session
      description: >-
        Creates a live ETA page (https://eta.page/...) for a job's recipient. If
        the job already has an active session (not revoked, not expired), that
        one is returned as it is and the body is ignored. Recipient fields
        default to the job's contact. Expiry defaults to 30 days, at most 90
        days. Status 200, not 201. Workers are refused with 403 (code
        permission_denied); an unknown job gives 400.
      operationId: createEtaSession
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EtaSessionCreate'
            example:
              jobId: '650000000000000000000001'
              recipientEmail: sam@example.com
              showMap: true
              expiresIn: 7d
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                  - error
                  - meta
                properties:
                  data:
                    type: object
                    required:
                      - session
                    properties:
                      session:
                        $ref: '#/components/schemas/EtaSession'
                  error:
                    type: 'null'
                  meta:
                    $ref: '#/components/schemas/Meta'
              example:
                data:
                  session:
                    id: eta_k7m2p9x4q8r3
                    token: k7m2p9x4q8r3
                    jobId: '650000000000000000000001'
                    placeId: p1q2r3
                    memberId: a1b2c3
                    recipientName: Sam Lee
                    recipientPhone: '+14155550102'
                    recipientEmail: sam@example.com
                    title: Install water heater
                    status: assigned
                    recipientStatus: unknown
                    etaWindowStart: 1793552400000
                    etaWindowEnd: 1793563200000
                    etaConfidence: scheduled
                    publicUrl: https://eta.page/K7M2-P9X4-Q8R3
                    apiUrl: https://api.hellotracks.com/api/eta/k7m2p9x4q8r3
                    showWorkerName: true
                    showMap: true
                    branding:
                      companyName: Example Plumbing
                      companyId: c1d2e3
                    viewedAt: 0
                    readyConfirmedAt: 0
                    accessNotes: ''
                    rescheduleRequestedAt: 0
                    rescheduleNote: ''
                    source: public_api
                    createdById: c1d2e3
                    createdByName: Example Plumbing
                    createdAt: 1793520000000
                    updatedAt: 1793520000000
                    expiresAt: 1796112000000
                    revokedAt: 0
                    expired: false
                    revoked: false
                    job:
                      id: '650000000000000000000001'
                      title: Install water heater
                      date: '2026-11-02'
                      status: assigned
                      progressCode: 1
                      timeWindow:
                        start: '09:00'
                        end: '12:00'
                      address: 500 Market St, San Francisco, CA 94105
                    recipientSafe:
                      ready: false
                      accessNotesAdded: false
                      rescheduleRequested: false
                error: null
                meta:
                  path: /v1/eta/sessions
                  method: POST
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  schemas:
    EtaSessionCreate:
      type: object
      additionalProperties: false
      required:
        - jobId
      properties:
        jobId:
          type: string
        recipientName:
          type: string
          description: Defaults to the job's contact name.
        recipientPhone:
          type: string
          description: Defaults to the job's contact phone.
        recipientEmail:
          type: string
          description: Defaults to the job's contact email.
        title:
          type: string
          description: Defaults to the job title, or 'Service visit'.
        showWorkerName:
          type: boolean
          description: Defaults to the company setting etaPageDefaultShowWorkerName.
        showMap:
          type: boolean
          description: Defaults to the company setting etaPageDefaultShowMap.
        expiresIn:
          type:
            - integer
            - string
          description: >-
            How long the link lives: milliseconds, or a number with m, h or d
            (30m, 24h, 30d). Default 30 days, at most 90 days. 'expires' wins
            over 'expiresIn'.
        expires:
          type:
            - integer
            - string
          description: Same as expiresIn.
      example:
        jobId: '650000000000000000000001'
        recipientEmail: sam@example.com
        showMap: true
        expiresIn: 7d
    EtaSession:
      type: object
      properties:
        id:
          type: string
          description: Session id, eta_ followed by 12 characters.
        token:
          type: string
          description: Public token of the eta.page link.
        jobId:
          type: string
        placeId:
          type: string
        memberId:
          type: string
          description: Assignee when the session was created.
        recipientName:
          type: string
        recipientPhone:
          type: string
        recipientEmail:
          type: string
        title:
          type: string
        status:
          $ref: '#/components/schemas/EtaSessionStatus'
        recipientStatus:
          type: string
        etaWindowStart:
          type: integer
          format: int64
          description: ms timestamp, 0 when unknown.
        etaWindowEnd:
          type: integer
          format: int64
          description: ms timestamp, 0 when unknown.
        etaConfidence:
          type: string
          description: >-
            scheduled, pending_schedule, live, trip_active, stale_location, or
            the terminal status.
        publicUrl:
          type: string
          format: uri
          description: https://eta.page/XXXX-XXXX-XXXX
        apiUrl:
          type: string
          format: uri
        showWorkerName:
          type: boolean
        showMap:
          type: boolean
        branding:
          type: object
          properties:
            companyName:
              type: string
            companyId:
              type: string
        viewedAt:
          type: integer
          format: int64
        readyConfirmedAt:
          type: integer
          format: int64
        accessNotes:
          type: string
        rescheduleRequestedAt:
          type: integer
          format: int64
        rescheduleNote:
          type: string
        source:
          type: string
          description: >-
            The HT-Integration-Source header of the create request, else
            public_api.
        createdById:
          type: string
        createdByName:
          type: string
        createdAt:
          type: integer
          format: int64
        updatedAt:
          type: integer
          format: int64
        expiresAt:
          type: integer
          format: int64
        revokedAt:
          type: integer
          format: int64
          description: 0 when not revoked.
        expired:
          type: boolean
        revoked:
          type: boolean
        job:
          type: object
          description: Left out when the job no longer exists.
          properties:
            id:
              type: string
            title:
              type: string
            date:
              type: string
              description: YYYY-MM-DD, empty string when the job has no date.
            status:
              $ref: '#/components/schemas/EtaSessionStatus'
            progressCode:
              type: integer
              description: >-
                0 unassigned, 1 scheduled, 2 accepted, 3 in progress, 4 success,
                5 failed.
            timeWindow:
              $ref: '#/components/schemas/JobTimeWindow'
            address:
              type: string
            completedAt:
              type: integer
              format: int64
        recipientSafe:
          type: object
          description: >-
            What the recipient did on the page. Left out when the job no longer
            exists.
          properties:
            ready:
              type: boolean
            accessNotesAdded:
              type: boolean
            rescheduleRequested:
              type: boolean
            completion:
              type: string
              enum:
                - completed
                - issue
            completedAt:
              type: integer
              format: int64
      example:
        id: eta_k7m2p9x4q8r3
        token: k7m2p9x4q8r3
        jobId: '650000000000000000000001'
        placeId: p1q2r3
        memberId: a1b2c3
        recipientName: Sam Lee
        recipientPhone: '+14155550102'
        recipientEmail: sam@example.com
        title: Install water heater
        status: assigned
        recipientStatus: unknown
        etaWindowStart: 1793552400000
        etaWindowEnd: 1793563200000
        etaConfidence: scheduled
        publicUrl: https://eta.page/K7M2-P9X4-Q8R3
        apiUrl: https://api.hellotracks.com/api/eta/k7m2p9x4q8r3
        showWorkerName: true
        showMap: true
        branding:
          companyName: Example Plumbing
          companyId: c1d2e3
        viewedAt: 0
        readyConfirmedAt: 0
        accessNotes: ''
        rescheduleRequestedAt: 0
        rescheduleNote: ''
        source: public_api
        createdById: c1d2e3
        createdByName: Example Plumbing
        createdAt: 1793520000000
        updatedAt: 1793520000000
        expiresAt: 1796112000000
        revokedAt: 0
        expired: false
        revoked: false
        job:
          id: '650000000000000000000001'
          title: Install water heater
          date: '2026-11-02'
          status: assigned
          progressCode: 1
          timeWindow:
            start: '09:00'
            end: '12:00'
          address: 500 Market St, San Francisco, CA 94105
        recipientSafe:
          ready: false
          accessNotesAdded: false
          rescheduleRequested: false
    Meta:
      type: object
      properties:
        path:
          type: string
          description: The request path, without /v1.
          example: /jobs
        method:
          type: string
          example: GET
    EtaSessionStatus:
      type: string
      enum:
        - scheduled
        - assigned
        - en_route
        - approaching
        - arrived
        - completed
        - cancelled
        - revoked
        - expired
        - unavailable
      description: >-
        scheduled (no assignee), assigned (not yet accepted), en_route /
        approaching (accepted or on a trip; approaching under 1 km), arrived
        (checked in or trip finished), completed, cancelled (job failed or
        deleted), revoked, expired, unavailable (job not found).
    JobTimeWindow:
      type: object
      description: >-
        Time window on the job's date, local time of the company, as HH:mm
        strings (24:00 allowed as the end).
      properties:
        start:
          type: string
          pattern: ^\d{2}:\d{2}$
          description: HH:mm. 00:00 when not set.
          example: '09:00'
        end:
          type: string
          pattern: ^\d{2}:\d{2}$
          description: HH:mm. 24:00 when not set.
          example: '12:00'
    ErrorEnvelope:
      type: object
      properties:
        data:
          type: 'null'
        error:
          $ref: '#/components/schemas/Error'
        meta:
          $ref: '#/components/schemas/Meta'
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Stable error code for programs.
          enum:
            - invalid_request
            - invalid_format
            - invalid_data
            - invalid_api_key
            - unknown_user
            - authentication_failed
            - forbidden
            - not_found
            - already_exists
            - throttled
            - not_ready
            - clock_invalid
            - force_logout
            - internal_error
            - unknown_error
        message:
          type: string
          description: Why it failed, for people.
  responses:
    BadRequest:
      description: The request is invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            data: null
            error:
              code: invalid_request
              message: date must be YYYY-MM-DD
            meta:
              path: /jobs
              method: GET
    Unauthorized:
      description: The API key is missing or invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            data: null
            error:
              code: invalid_api_key
              message: Invalid Hellotracks API key.
            meta:
              path: /jobs
              method: GET
    Forbidden:
      description: The key may not do this.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            data: null
            error:
              code: forbidden
              message: No permission.
            meta:
              path: /jobs
              method: GET
    TooManyRequests:
      description: Too many requests; slow down.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            data: null
            error:
              code: throttled
              message: Too many requests.
            meta:
              path: /jobs
              method: GET
    ServerError:
      description: Hellotracks failed; retry later.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            data: null
            error:
              code: internal_error
              message: Hellotracks API is temporarily unavailable.
            meta:
              path: /jobs
              method: GET
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: API-Key
      description: >-
        Your API key, from More → API & Integrations in the dashboard, or from
        ht signup / ht auth login.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.