Introduction
Parley’s USCIS Case Status API exposes the same status-tracking capabilities used in our AI-native case management to programmatically monitor case movement, normalize USCIS messages into consistent categories, and receive webhooks when statuses change. The API is provisioned per tenant during a closed beta and builds on the official USCIS Torch Case Status API, adding normalization, subscriptions, and delivery semantics suitable for production systems. See product context that “the USCIS API is live” and case tracking is integrated into Applicant Profiles. Also see RFE tracking and instant status updates. For platform overview and security posture, start at the main site.
Who this API is for
-
Law firms and legal ops teams building internal dashboards, alerts, or SLAs on top of live USCIS case movement.
-
Immigration-tech vendors integrating case tracking into client portals or CRMs.
-
Corporate mobility teams aggregating case statuses across counsel.
Example outcomes include inbox-free case alerts, auto-updated queues when RFEs issue, and portfolio-level reporting on approvals and denials. These are the same workflows our web app surfaces in AI-native case management.
Access and authentication (beta)
-
Access: Invite-only beta; tenants are provisioned with an API base URL, credentials, and webhook signing secret.
-
Authentication: Bearer token in Authorization header. Keys are tenant-scoped.
-
Environments: Production multi-tenant; private cloud available for enterprises with data residency or isolation needs.
-
Onboarding: Request access via the contact form.
Base URL, versioning, and idempotency
-
Base URL: Provided during onboarding as PARLEY_API_BASE (use this variable in examples).
-
Versioning: URI-based (e.g., /v1). Breaking changes are released under a new version.
-
Idempotency: All webhook deliveries include idempotency keys; write endpoints accept optional Idempotency-Key headers for safe retries.
Normalized status taxonomy
The API maps raw USCIS text into a compact set of stable categories designed for automation and analytics.
| Normalized status | Description |
|---|---|
| received | USCIS acknowledged receipt; case accepted and pending initial processing. |
| rfe_issued | USCIS issued a Request for Evidence. |
| rfe_received | USCIS confirmed receipt of an RFE response. |
| approved | Case approved. |
| denied | Case denied. |
| interview_scheduled | Interview scheduled. |
| other | Any status that does not cleanly map to the above (raw text preserved). |
Note: These categories reflect the beta taxonomy and may expand. See references to live tracking in our product updates.
Endpoints
All requests use JSON. Replace PARLEY_API_BASE with your tenant base URL.
GET /v1/case-status
Retrieve the latest status for a receipt number.
Query parameters:
- receipt (string, required): USCIS receipt number (e.g., IOE0912345678)
Example request:
curl -s \
-H "Authorization: Bearer $PARLEY_API_TOKEN" \
"$PARLEY_API_BASE/v1/case-status?receipt=IOE0912345678"
Example response:
{
"receipt_number": "IOE0912345678",
"normalized_status": "rfe_issued",
"raw_status_text": "We sent you a request for evidence...",
"last_updated_at": "2025-10-14T19:22:03Z"
}
GET /v1/events
Return the status change history for a receipt.
Query parameters:
-
receipt (string, required)
-
limit (int, optional; default 50)
-
before (ISO8601 timestamp, optional)
Example:
curl -s \
-H "Authorization: Bearer $PARLEY_API_TOKEN" \
"$PARLEY_API_BASE/v1/events?receipt=IOE0912345678&limit=20"
Response:
{
"receipt_number": "IOE0912345678",
"events": [
{
"type": "case.status.updated",
"normalized_status": "approved",
"raw_status_text": "Case Was Approved",
"occurred_at": "2025-11-02T16:01:17Z"
},
{
"type": "case.status.updated",
"normalized_status": "rfe_received",
"raw_status_text": "Response To USCIS' Request For Evidence Was Received",
"occurred_at": "2025-10-25T11:48:05Z"
}
]
}
POST /v1/receipts
Register one or more receipt numbers for tracking and enrichment.
Request:
curl -s -X POST "$PARLEY_API_BASE/v1/receipts" \
-H "Authorization: Bearer $PARLEY_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 1c0b2f4e-8e3d-4ad8-9e6e-1a7b1b1a0f00" \
-d '{
"receipts": [
{ "receipt_number": "IOE0912345678", "label": "Acme-O1A" },
{ "receipt_number": "IOE0976543210" }
]
}'
Response:
{
"registered": ["IOE0912345678", "IOE0976543210"],
"already_registered": []
}
POST /v1/subscriptions
Create a webhook subscription for case events.
Request:
curl -s -X POST "$PARLEY_API_BASE/v1/subscriptions" \
-H "Authorization: Bearer $PARLEY_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "<your webhook endpoint>",
"events": ["case.status.updated"],
"secret": "optional-override-secret"
}'
Response:
{
"id": "sub_01HFQ4...",
"url": "<your webhook endpoint>",
"events": ["case.status.updated"],
"created_at": "2025-12-12T20:10:00Z"
}
GET /health
Probe service readiness.
curl -s "$PARLEY_API_BASE/health"
Response:
{ "status": "ok" }
Webhooks
When a tracked receipt changes status, we enqueue a delivery to each matching subscription.
-
Event types (beta): case.status.updated, case.rfe.issued, case.rfe.received, case.approved, case.denied, case.interview.scheduled.
-
Security: Each delivery is signed with a shared-secret HMAC and includes an idempotency key. Verify the signature before processing.
-
Retries: Exponential backoff; deliveries are retried on non-2xx responses. Duplicate deliveries are possible; use the idempotency key.
Example payload:
POST <your webhook endpoint>
Headers:
Content-Type: application/json
Authorization: Parley-Signature=t=1734020000,v1=hexdigest
Idempotency-Key: 4a4d1c6f-6c1e-4b1e-9f9a-2a1d0c0f9b44
Body:
{
"id": "evt_01HFQ5...",
"type": "case.status.updated",
"receipt_number": "IOE0912345678",
"normalized_status": "rfe_issued",
"raw_status_text": "We sent you a request for evidence...",
"occurred_at": "2025-10-14T19:22:03Z"
}
Example handler (Node.js/Express):
import crypto from 'crypto';
import express from 'express';
const app = express();
app.use(express.json({ type: 'application/json' }));
const WEBHOOK_SECRET = process.env. PARLEY_WEBHOOK_SECRET;
function verifySignature(body, header) {
const [tsPart, sigPart] = String(header || '').split(',');
const timestamp = tsPart?.split('=')[1];
const signature = sigPart?.split('=')[1];
const payload = `${timestamp}.${JSON.stringify(body)}`;
const expected = crypto.createHmac('sha256', WEBHOOK_SECRET).update(payload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature || ''));
}
app.post('/webhooks/parley', (req, res) => {
const sig = req.get('Authorization');
if (!verifySignature(req.body, sig)) return res.status(400).send('invalid signature');
const idemp = req.get('Idempotency-Key');
// dedupe by idemp key in your datastore before processing
// handle event
const evt = req.body; // evt.type, evt.normalized_status, evt.receipt_number
res.status(200).send('ok');
});
app.listen(3000);
API reference: object schemas (beta)
These schemas reflect the beta and may change.
-
CaseStatus
-
receipt_number: string
-
normalized_status: enum(received, rfe_issued, rfe_received, approved, denied, interview_scheduled, other)
-
raw_status_text: string
-
last_updated_at: string (ISO8601)
-
Event
-
id: string
-
type: string (e.g., case.status.updated)
-
receipt_number: string
-
normalized_status: enum(...as above)
-
raw_status_text: string
-
occurred_at: string (ISO8601)
-
Subscription
-
id: string
-
url: string (HTTPS)
-
events: array[string]
-
created_at: string (ISO8601)
-
Error
-
error: string (machine-readable code)
-
message: string (human-readable)
-
request_id: string
Data freshness and semantics
-
Source: The service consumes official USCIS status data via the USCIS Torch Case Status API and preserves the raw text for audit and user display, while adding normalized categories suitable for automation.
-
Latency: Propagation delay can occur between USCIS publication and webhook delivery; do not treat events as legal notice.
-
Completeness: Some case types or legacy records may return only partial history; we return raw text as-is in those cases. See live tracking notes.
Errors and rate limits
-
HTTP status codes: 200/201 success; 400 validation; 401/403 auth; 404 not found; 409 conflict (idempotency); 429 rate limit; 5xx transient.
-
Rate limits: Reasonable per-tenant limits apply during beta; contact support for higher quotas.
Security and compliance
-
Data handling: Case identifiers and status text are processed under Parley’s privacy policy and terms.
-
Platform posture: Parley markets SOC 2 Type 2 and GDPR compliance and provides a trust-centered approach to logging and access controls. Confirm certifications directly with Parley during procurement.
Related product capabilities
Case tracking is integrated with AI-native case management (Applicant and Petitioner Profiles) and RFE workflows in the Parley web app, enabling end-to-end automation alongside this API surface. See product updates for details.
Getting access
-
Request beta access or an enterprise private-cloud deployment via the contact page.
-
During onboarding you will receive: API base URL, tenant-scoped API key, webhook signing secret, and quota defaults.
Additional references
-
Platform overview and security posture.
-
Media coverage of Parley’s immigration automation and case assembly (context for why firms automate).
-
Independent vendor overview.