1. Overview
Connect Oyster contractor engagements to 1099Policy to ensure every engagement has proper insurance coverage or a validated Certificate of Insurance (COI) on file.
You can:
- Bind fractional, on-demand coverage for Oyster contractor engagements.
- Automatically validate and store COIs.
- Keep compliance states synced through 1099Policy webhooks (
policy.*,certificate.*). - Map Oyster compensation to 1099Policy
job.wage(integer cents) andwage_type. - Persist Oyster IDs in
custom_metadatafor reconciliation (never as primary IDs).
2. Integration Timing & Trigger
Coverage should begin as soon as an engagement is finalized or its start date is set. Because Oyster does not emit a “work started” event, coverage must be bound before any services begin.
Use Oyster Webhooks to start your flow when a contractor engagement is finalized or ready for work.
- Primary trigger: engagement/contract finalized or signed (terms confirmed).
- Alternate triggers: invoice schedule created or engagement start date set (signals work is imminent).
- Event delivery: via Oyster Webhooks.
3. Core Concepts
Each Oyster object maps to a 1099Policy resource to maintain insurance coverage and COI validation through the engagement lifecycle.
| Oyster Object | 1099Policy Resource | Description |
|---|---|---|
| Engagement | Job + Assignment | Defines scope, compensation, and coverage window |
| Contractor | Contractor | Must exist before quoting |
| Document (COI) | Certificate | Validates contractor coverage |
| Invoice | Invoice | Optional for reconciliation |
| Engagement ID | custom_metadata.engagement_id | Used for reconciliation only |
4. End-to-End Implementation
Follow these steps to automate Oyster → 1099Policy integration.
4.1 Create Contractor
Each Oyster Contractor must exist in 1099Policy before quotes or assignments are created. Every Contractor must include a unique contact.email. Generate a proxy email if missing (e.g., <contractor_id>@relay.yourdomain.com).
| Oyster Field | 1099Policy Contractor | Notes |
|---|---|---|
contractor.id | custom_metadata.oyster_contractor_id | Reconciliation key |
first_name, last_name | contractor.first_name, contractor.last_name | Required |
email | contractor.email | Required; proxy allowed |
country | address.country | Optional |
region | address.region | Required |
Source: Oyster (REST)
GET https://api.oysterhr.com/v1/contractors/{contractor_id}
Authorization: Bearer oy_live_***
Destination: 1099Policy (POST /contractors)
POST https://api.1099policy.com/api/v1/contractors
Authorization: Bearer t9k_test_***
Content-Type: application/json
{
"contact": {
"first_name": "Jordan",
"last_name": "Lee",
"email": "ctr_821@relay.yourdomain.com"
},
"address": {
"country": "US",
"region": "CA"
},
"custom_metadata": {
"oyster_contractor_id": "ctr_821"
}
}
4.2 Create Job
Create a Job in 1099Policy to capture the engagement’s scope, compensation, and jurisdiction.
| 1099Policy Job Field | Oyster Source | Notes |
|---|---|---|
name | Engagement title | Human-readable name |
description | Engagement SOW or description | Scope |
entity | Internal client/account ID | Must exist in 1099Policy |
category_code | Role/job family → mapped 1099Policy category | Maintain mapping |
wage (cents) | Rate or invoice amount × 100 | Required |
wage_type | "flatfee" or "hourly" | Required |
region | Engagement country or region | Defaults to contractor home state |
custom_metadata.engagement_id | Engagement ID | Reconciliation |
Destination: 1099Policy (POST /jobs)
POST https://api.1099policy.com/api/v1/jobs
Authorization: Bearer t9k_test_***
Content-Type: application/json
{
"name": "Product Landing Page — Contractor",
"description": "Design + build LP for Q4 launch",
"entity": "en_12AbC3",
"category_code": "MARKETING_WEB",
"wage": 450000,
"wage_type": "flatfee",
"region": "US",
"custom_metadata": { "engagement_id": "eng_8a7f" }
}
4.3 Create Quote
Create a Quote to define coverage requirements and link to the Job.
| 1099Policy Quote Field | Oyster Source | Notes |
|---|---|---|
contractor | Mapped contractor ID | Must exist first |
job | Returned Job ID | Required |
coverage_type[] | Required coverage | e.g., ["general","workers-comp"] |
effective_date | Engagement start date (epoch UTC) | Coverage start |
end_date | Engagement end date (epoch UTC) | Coverage end |
custom_metadata.engagement_id | Engagement ID | Reconciliation |
Destination: 1099Policy (POST /quotes)
POST https://api.1099policy.com/api/v1/quotes
Authorization: Bearer t9k_test_***
Content-Type: application/json
{
"contractor": "cn_Kh18Qs",
"job": "jb_Dl9n42",
"coverage_type": ["general","workers-comp"],
"effective_date": 1764300000,
"end_date": 1766892000,
"custom_metadata": { "engagement_id": "eng_8a7f" }
}
4.4 Create Insurance Application Session
Redirect contractors to complete their first policy opt-in and bind coverage using the insurance application session endpoint.
Destination: 1099Policy (POST /apply/sessions)
POST https://api.1099policy.com/api/v1/apply/sessions
Authorization: Bearer t9k_test_***
Content-Type: application/json
{
"quote": "qt_Pf5LmA",
"success_url": "https://app.oysterhr.com/engagements/eng_8a7f?coverage=active",
"cancel_url": "https://app.oysterhr.com/engagements/eng_8a7f?coverage=canceled",
"custom_metadata": { "engagement_id": "eng_8a7f" }
}
4.5 Create Assignment
Assignments apply coverage automatically for returning contractors who have already completed their opt-in.
Destination: 1099Policy (POST /assignments)
POST https://api.1099policy.com/api/v1/assignments
Authorization: Bearer t9k_test_***
Content-Type: application/json
{
"contractor": "cn_Kh18Qs",
"job": "jb_Dl9n42",
"effective_date": 1764300000,
"end_date": 1766892000,
"coverage_type": ["general","workers-comp"],
"custom_metadata": { "engagement_id": "eng_8a7f" }
}
4.6 Upload Certificate (BYO-COI)
Upload contractor-provided COIs for validation.
Destination: 1099Policy (POST /files/certificates)
(multipart upload)
Fields:
certificate=@file.pdfcontractor=cn_Kh18Qscustom_metadata[engagement_id]=eng_8a7f
4.7 Record Invoice (Optional)
If the contractor’s actual payment differs from the original rate, record the final remuneration using the Invoice API. This step is optional and does not affect insurance coverage.
Destination: 1099Policy (POST /invoices)
POST https://api.1099policy.com/api/v1/invoices
Authorization: Bearer t9k_test_***
Content-Type: application/json
{
"contractor": "cn_ti8eXviE4A",
"job": "jb_rajdrwMUKi",
"gross_pay": 1200,
"paycycle_startdate": 1714419793,
"paycycle_enddate": 1714419793
}
Use Unix seconds (UTC) for paycycle_startdate and paycycle_enddate. See full API reference: https://docs.1099policy.com/group/endpoint-invoice
5. Webhooks
Oyster and 1099Policy webhooks synchronize engagement, invoice, and coverage events.
| Source | Event | Action |
|---|---|---|
| Oyster | Engagement finalized | Trigger Job + Quote creation |
| Oyster | Invoice issued | Record invoice reference |
| 1099Policy | application.started | Mark “Coverage in progress.” |
| 1099Policy | policy.active | Mark “Insured”; store policy ID. |
| 1099Policy | policy.canceled / policy.expired | Mark “Not insured.” |
| 1099Policy | certificate.validated | Mark COI valid. |
| 1099Policy | certificate.flagged | Trigger manual review. |
6. Testing Checklist
- Contractor created with proxy email if missing
- Job created with wage and metadata mapping
- Quote created with coverage types and dates
- Application Session launched and redirects properly
- Assignment matches engagement term
- COI uploads validated via webhook
- Optional invoice recorded for actual pay reconciliation
7. References
- Oyster Public API: https://docs.oysterhr.com/docs
- Oyster Webhooks: https://docs.oysterhr.com/docs/getting-started-with-webhooks
- Engagements API: https://docs.oysterhr.com/reference/get_v1-engagements
- Invoices Overview: https://support.oysterhr.com/hc/en-us/articles/34395399220753-How-and-when-are-invoices-generated-for-contractors

