📍 Attempts
Attempts API
Attempts are individual service attempts made against a job. Each attempt records the outcome, timestamp, GPS coordinates, and narrative. All attempts are immutable once created.
List Attempts
GET
/jobs/:id/attempts
Returns all service attempts for a given job, ordered by sequence_number ascending.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| id required | uuid | The job's unique identifier |
Attempt Object Fields
| Field | Type | Description |
|---|---|---|
| id | uuid | Unique attempt identifier |
| job_id | uuid | Parent job identifier |
| sequence_number | integer | 1-based attempt count for this job |
| outcome | string | One of the outcome values below |
| attempted_at | ISO 8601 | Timestamp of the actual attempt (immutable) |
| gps_lat | float | Latitude at time of attempt |
| gps_lng | float | Longitude at time of attempt |
| gps_verified | boolean | true if GPS coords were within 500m of service address |
| narrative | string | Free-text description of what occurred |
| server_id | uuid | Server who made the attempt |
| server_name | string | Server's display name |
| logged_by_id | uuid | User who logged the attempt (may differ from server) |
| photo_count | integer | Number of photos attached to this attempt |
| diligence_windows_satisfied | object | Boolean flags: morning, afternoon, weekend |
| substitute_name | string | null | For substitute service: name of person served |
| substitute_relationship | string | null | Relationship to defendant (e.g., "spouse") |
| substitute_age | integer | null | Age of substitute (must be 18+) |
| created_at | ISO 8601 | When this attempt record was created |
Outcome Values
served
substitute_service
no_answer
refused
evading
wrong_address
other
Example Response
json
{ "data": [ { "id": "a1b2c3d4-1111-2222-3333-444455556666", "job_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d", "sequence_number": 1, "outcome": "no_answer", "attempted_at": "2025-04-12T08:22:00Z", "gps_lat": 30.2276, "gps_lng": -97.7481, "gps_verified": true, "narrative": "Knocked 3 times, lights on, no response. Vehicle in driveway.", "server_id": "b4d5e6f7-2b3c-4d5e-6f7g-8h9i0j1k2l3m", "server_name": "Marcus Webb", "logged_by_id": "b4d5e6f7-2b3c-4d5e-6f7g-8h9i0j1k2l3m", "photo_count": 2, "diligence_windows_satisfied": { "morning": true, "afternoon": false, "weekend": false }, "substitute_name": null, "substitute_relationship": null, "substitute_age": null, "created_at": "2025-04-12T08:24:11Z" } ], "meta": { "page": 1, "per_page": 50, "total": 2 } }
Log Attempt
POST
/jobs/:id/attempts
Logs a new service attempt against a job. The attempt is immutable once created — attempted_at cannot be changed after the fact.
attempted_at is the time of the actual attempt — not the time of the API call. If a server makes an attempt in the field and logs it an hour later, pass the actual attempt time. This timestamp is immutable after creation.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| outcome | string | required | One of the valid outcome values |
| attempted_at | ISO 8601 | required | Actual timestamp of the attempt. Immutable after creation. |
| narrative | string | optional | Description of what occurred at the attempt |
| gps_lat | float | optional | Latitude — triggers GPS verification against service address |
| gps_lng | float | optional | Longitude |
| substitute_name | string | optional | Required if outcome is substitute_service |
| substitute_relationship | string | optional | Required if outcome is substitute_service |
| substitute_age | integer | optional | Required if outcome is substitute_service. Must be 18 or older. |
Outcome Examples
No Answer
json — POST body
{ "outcome": "no_answer", "attempted_at": "2025-04-14T07:45:00Z", "gps_lat": 30.2276, "gps_lng": -97.7481, "narrative": "Knocked multiple times, rang doorbell. No response. Lights visible inside." }
Served (Personal Service)
json — POST body
{ "outcome": "served", "attempted_at": "2025-04-15T09:12:00Z", "gps_lat": 30.2276, "gps_lng": -97.7481, "narrative": "Subject answered door, confirmed identity as James R. Thornton. Documents delivered in hand." }
Substitute Service
json — POST body
{ "outcome": "substitute_service", "attempted_at": "2025-04-15T18:30:00Z", "gps_lat": 30.2276, "gps_lng": -97.7481, "substitute_name": "Linda M. Thornton", "substitute_relationship": "spouse", "substitute_age": 52, "narrative": "Spouse answered, stated subject lives at residence. Documents left with spouse who agreed to forward." }
Response — 201 Created
json
{ "data": { "id": "b2c3d4e5-2222-3333-4444-555566667777", "job_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d", "sequence_number": 3, "outcome": "substitute_service", "attempted_at": "2025-04-15T18:30:00Z", "gps_verified": true, "photo_count": 0, "created_at": "2025-04-15T18:34:22Z" } }
Uploading Photos
Photos are uploaded separately after creating an attempt, using a multipart form POST. This keeps the attempt creation response fast and allows multiple photos to be uploaded in parallel.
POST
/attempts/:id/photos
Upload a photo for an attempt. Use multipart/form-data encoding. Accepted formats: JPEG, PNG, HEIC. Max 10MB per photo, max 10 photos per attempt.
bash
curl -X POST https://api.proxiant.co/v1/attempts/a1b2c3d4-1111-2222-3333-444455556666/photos \ -H "Authorization: Bearer prx_live_xxxxxxxxxxxx" \ -F "photo=@/path/to/doorstep.jpg"
Photos are linked to the attempt and included when generating affidavits. Requires
attempts:write scope.