New integration? Follow the quickstart to create an application, manage members and receive status updates.
Create applications, issue applicant sign-in links, manage access and retrieve onboarding outcomes from your backend. Use this reference for request fields, response bodies and error handling.
Start with the integration guide for a working flow from intake selection to outcome reconciliation. Arrange your tenant and API credentials with Aurora Edge. Examples use synthetic records and credential placeholders.
POST and PATCH bodies use JSON. GET and DELETE have no body. Replace path placeholders in braces with returned IDs, keep IDs opaque and use the exact documented path. The current router matches the whole path and tolerates a trailing slash.
Call from your backend
Keep keys in your server secret manager. CORS is disabled and OPTIONS returns 405 with an empty body. Your frontend opens the returned loginUrl without receiving an API key. Sentinel credentials and Firebase staff callable tokens do not authenticate this API.
The key selects one tenant; sending tenantId cannot select another. Request the scopes your integration needs. Keys issued without explicit scopes grant applications:write only.
Scope
Grants
applications:write
Provisioning, sign-in links, membership and lock/unlock.
applications:read
Application, information-request, intake, checklist and document metadata reads.
webhooks:manage
Webhook registration, configuration, secret rotation, test sends and delivery history.
A valid key without a required scope returns 403 permission-denied naming that scope. Ask Aurora Edge to issue the scopes you need. Rotation and revocation invalidate the old credential immediately. For a gradual cutover, arrange a second key, switch callers, verify them and revoke the first. See Administration.
Success bodies are JSON except 204, which has no body. Collections use data arrays. Intake and information-request lists are unpaged. Timestamps are RFC 3339 UTC with milliseconds, for example 2026-09-10T09:00:00.000Z. Nullable fields return null when unavailable; optional fields may be omitted. Accept additive response fields. Webhook signature timestamps use Unix seconds.
Application status
Client interpretation
pending
Created or awaiting staff review. Submission can leave this status unchanged.
needs_info
The applicant owes information. Read requests and direct them to the portal.
hold
The case is on hold. Never on_hold.
pending_approval
Approval proposed, awaiting a second approver.
active
Approved. There is no approved status string.
rejected
Rejected; the application read includes rejectionReason.
These are onboarding states, not transport success. Store unknown future values without treating them as approval. See Onboarding lifecycle.
POST /v1/applications
Create an application without minting a sign-in link.
Required scope:applications:write.
Request. Send a JSON body.
Field
Type
Description
emailrequired
string
Applicant email, trimmed and lowercased. Required, must contain @, maximum 320 characters.
externalRef
string
Your stable application reference. Trimmed and cut to 200 characters. Used as the identity instead of email when nonempty. Send the same value on every repeat.
companyName
string
Display name. Trimmed and cut to 200 characters. Defaults to email; a repeat does not rename the application.
labelId
string
Intake label from GET /v1/intakes. When absent, uses the first usable intake in configured order. Send an explicit label when you support multiple intakes. A repeat does not change an existing application intake.
Current lifecycle status. A new application is pending. A repeat returns its stored status.
400 invalid-argument for invalid email, unknown labelId or no usable intake; 400 failed-precondition for an unusable intake configuration or full membership roster on a repeat that would add a member.
409 already-exists when an externalRef is bound to another applicant email. Correct your reference or email; do not retry unchanged.
403 permission-denied for a suspended tenant or locked application; 410 failed-precondition for an erased application. Missing or foreign application IDs return 404 not-found.
A repeat can restore the original applicant membership if it was removed, subject to the 20-member limit. Use the dedicated reissue route for a new link to an existing case.
POST /v1/login-sessions
Provision an application and return a sign-in link for the supplied applicant.
Required scope:applications:write.
Request. Send a JSON body.
Field
Type
Description
emailrequired
string
Applicant email, trimmed and lowercased. Required, must contain @, maximum 320 characters.
externalRef
string
Your stable application reference. Trimmed and cut to 200 characters. Used as the identity instead of email when nonempty. Send the same value on every repeat.
companyName
string
Display name. Trimmed and cut to 200 characters. Defaults to email; a repeat does not rename the application.
labelId
string
Intake label from GET /v1/intakes. When absent, uses the first usable intake in configured order. Send an explicit label when you support multiple intakes. A repeat does not change an existing application intake.
redirectPath
string
Optional landing page: /upload-documents, /status, /form-parser, /dashboard or /requests. Other values are ignored; the portal chooses the page from the application state.
pending, hold, needs_info, pending_approval, active or rejected. active means approved.
createdAt
string | null
RFC 3339 UTC application creation time.
updatedAt
string | null
RFC 3339 UTC application update time.
submittedAt
string | null, optional
Omitted when no submission timestamp is stored. Legacy submissions may have no timestamp; absence alone does not prove non-submission.
rejectionReason
string | null, optional
Customer-visible reason. Present only when status is rejected.
decision
object | null
Latest decision, or null when none exists.
decision.action
string | null
Decision action, such as needs_info, approve, approved, reject, hold or proposal_rejected. Separate from application status.
decision.fromStatus
string | null
Application status before the decision.
decision.toStatus
string | null
Application status resulting from the decision.
decision.byRole
string | null
Actor role. No staff email is returned.
decision.comment
string | null
Applicant-visible staff comment.
decision.at
string | null
RFC 3339 UTC decision time.
openInfoRequest
object | null
Current request summary. Can remain populated while staff review a responded request.
openInfoRequest.requestId
string | null
Information-request ID.
openInfoRequest.seq
number | null
Request sequence within this application.
openInfoRequest.round
number | null
Response round within this request.
openInfoRequest.openItems
number | null
Items requiring applicant action.
openInfoRequest.answeredItems
number | null
Answered items awaiting staff review.
openInfoRequest.at
string | null
RFC 3339 UTC summary timestamp.
members
array
All members, unpaged. Maximum 20 members.
members[].uid
string | null
Opaque member ID; use it for removal and ownership handover.
members[].email
string | null
Normalized member email.
members[].role
string | null
applicant or teammate. This is not a staff role and does not identify the current owner after a handover.
members[].joinedAt
string | null
RFC 3339 UTC membership creation time. Preserved on repeat addition.
Missing, foreign and erased applications return the same 404 not-found. Reads remain available for locked applications and suspended tenants with a valid read key.
No risk scores, screening results, form answers, document contents or internal staff notes are returned. There is no accessActive or ownerUid field in this read response.
This is the current snapshot. Submission can leave status pending; do not equate pending with an incomplete form.
GET /v1/applications/{clientId}/info-requests
List information requests and the prompts the applicant must address.
Required scope:applications:read.
Request. No request body.
Field
Type
Description
clientIdrequired
string (path)
Application ID returned by provisioning.
Example request
GET /v1/applications/{clientId}/info-requests HTTP/1.1
Host: aegis-api.theauroraedge.com
Authorization: Bearer aegis_<key-id>_<secret>
All requests, unpaged, highest seq first. Empty array when none exist. No limit or cursor parameters.
data[].requestId
string | null
Request identifier.
data[].seq
number | null
Request sequence within the application. Distinct from webhook data.sequence.
data[].round
number | null
Response round within the request.
data[].status
string
open, responded, closed or cancelled. Active request status is derived from its items.
data[].openItems
number
Count of open and reopened items requiring applicant action.
data[].answeredItems
number
Count of answered items awaiting staff review.
data[].comment
string | null
Staff-written request comment visible to the applicant.
data[].createdAt
string | null
RFC 3339 UTC timestamp, null when the corresponding action has not occurred or no timestamp is stored.
data[].updatedAt
string | null
RFC 3339 UTC timestamp, null when the corresponding action has not occurred or no timestamp is stored.
data[].respondedAt
string | null
RFC 3339 UTC timestamp, null when the corresponding action has not occurred or no timestamp is stored.
data[].closedAt
string | null
RFC 3339 UTC timestamp, null when the corresponding action has not occurred or no timestamp is stored.
data[].cancelledAt
string | null
RFC 3339 UTC timestamp, null when the corresponding action has not occurred or no timestamp is stored.
data[].items
array
Request items and the prompts visible to the applicant.
data[].items[].itemId
string | null
Item identifier.
data[].items[].type
string | null
question, field or document.
data[].items[].prompt
string | null
Staff-written prompt. No applicant answer is returned.
data[].items[].status
string | null
open, answered, accepted or reopened.
Same 404 and read-access rules as the application read.
Applicant answers, uploaded files, filenames, correction values, staff actors and item event history are excluded. Answers and uploads must be supplied in the applicant portal.
GET /v1/intakes
Discover labels usable for provisioning.
Required scope:applications:read.
Request. No request body.
Example request
GET /v1/intakes HTTP/1.1
Host: aegis-api.theauroraedge.com
Authorization: Bearer aegis_<key-id>_<secret>
Unpaged labels with an attached intake pair, sorted by order ascending. Ties preserve configured order.
data[].labelId
string | null
Value to send when provisioning. A null value signals a configuration problem; ask staff to correct it.
data[].name
string | null
Display name.
data[].order
number | null
Configured ordering value. Missing or invalid order sorts as zero.
No configured usable labels returns 200 with data: [], while attempting to create then returns 400.
Missing tenant returns 404. Suspension does not block this read. Internal pair IDs, form fields and risk rules are not exposed.
POST /v1/applications/{clientId}/login-sessions
Mint a fresh link for an existing application without provisioning or adding a member.
Required scope:applications:write.
Request. Send a JSON body.
Field
Type
Description
clientIdrequired
string (path)
Application ID returned by provisioning.
email
string
Optional email naming an existing member. If absent or null, selects the current owner, falling back to the original applicant when no owner is stored.
redirectPath
string
Optional landing page: /upload-documents, /status, /form-parser, /dashboard or /requests. Other values are ignored; the portal chooses the page from the application state.
Single-use credential. Redirect to this exact URL or send it privately to the intended member; never log it.
clientId
string
Permanent application identifier. Store it against your own record.
expiresAt
string
RFC 3339 UTC expiry. Links live three days. Read this field; no ttl parameter is supported.
400 failed-precondition for an email that is invalid or is not an existing member, or when the application has no applicant email. Use POST members before minting a teammate link.
403 permission-denied for a suspended tenant or locked application; 410 failed-precondition for an erased application. Missing or foreign application IDs return 404 not-found.
No ttl parameter. Each successful call mints a fresh three-day, single-use link. After ownership handover, omit email only if you intend to target the new owner.
POST /v1/applications/{clientId}/members
Add portal access for one person. This call does not send an email or mint a link.
Required scope:applications:write.
Request. Send a JSON body.
Field
Type
Description
clientIdrequired
string (path)
Application ID returned by provisioning.
emailrequired
string
Member email, trimmed and lowercased, containing @ and at most 320 characters.
Opaque member ID; use it for removal and ownership handover.
email
string | null
Normalized member email.
role
string | null
applicant or teammate. This is not a staff role and does not identify the current owner after a handover.
joinedAt
string | null
RFC 3339 UTC membership creation time. Preserved on repeat addition.
Repeat addition of the same member is idempotent and preserves joinedAt. Maximum 20 members; adding a new person at the cap returns 400 failed-precondition. Invalid email returns 400 invalid-argument.
403 permission-denied for a suspended tenant or locked application; 410 failed-precondition for an erased application. Missing or foreign application IDs return 404 not-found.
Read the application to confirm membership, then use its login-sessions route with this email to issue a link.
DELETE /v1/applications/{clientId}/members/{uid}
Remove a member, with ownership handover when needed.
Required scope:applications:write.
Request. No request body.
Field
Type
Description
clientIdrequired
string (path)
Application ID returned by provisioning.
uidrequired
path string
Member ID from the application members array.
newOwnerUid
query string
Required when removing the current owner. Must name another existing member, never the removed member. Keep ownership in your integration record; the application read does not return ownerUid.
Missing or foreign application returns 404. Removing a nonmember, omitting a required handover or naming an invalid new owner returns 400 failed-precondition.
Removal is allowed while the tenant is suspended or the application is locked. An own-tenant erased record reaches membership validation and normally refuses because erasure clears membership.
A repeat removal returns 400 rather than replaying 204. After an ambiguous network failure, read the roster before retrying. Ownership handover does not change the original applicantEmail or the member role labels.
POST /v1/applications/{clientId}/lock
Disable applicant portal access without deleting the case or changing its decision.
Repeating the same action returns 200 with the same access state. Missing or foreign application: 404. Erased application: 410 failed-precondition.
Lock remains allowed during tenant suspension. New links, new members and repeated provisioning are refused while locked; tenant reads and member removal remain available.
Locking is not cancellation or erasure. There is no cancelled application status.
Repeating the same action returns 200 with the same access state. Missing or foreign application: 404. Erased application: 410 failed-precondition.
Unlock is refused with 403 permission-denied while the tenant is suspended, including a repeated unlock. Missing tenant returns 404.
Locking is not cancellation or erasure. There is no cancelled application status.
Idempotency and safe retries
Provisioning identity is tenant plus externalRef when nonempty, otherwise tenant plus normalized email. The same identity returns the same clientId. Keep externalRef stable and within 200 characters, and persist clientId. Changing or omitting a reference can create a second case. A different email on a known externalRef returns 409 without adding a member.
A repeat does not edit company name or intake. It can update the timestamp and restore original applicant membership. Use the dedicated reissue route for an existing case. Login-session calls mint a fresh ticket; member-add preserves existing membership; lock/unlock returns the resulting state. A repeated member removal returns 400 once the member is gone.
Reconcile an uncertain write before repeating it
A timeout or 5xx does not prove that no writes occurred. Retain the same application identity and use the corresponding read to reconcile. Creating another login session, registration or secret rotation can produce a new credential or resource.
Errors
Errors contain code, message and requestId inside error, plus details for some validation failures. OPTIONS is the empty-body exception.
requestId matches Aegis-Request-Id. details, when present, is an array of field and issue objects; only some validation errors supply it. Do not branch on message text. Server errors omit details and use a generic message.
HTTP
Code
Action
400
invalid-argument
Correct email, intake label, query or subscription parameter.
400
failed-precondition
Resolve intake configuration, member cap, reissue recipient or required ownership handover.
401
unauthorized
Check key format and active status; do not retry an invalid credential unchanged.
403
permission-denied
Check scope, tenant suspension and application lock. Granting and revoking access have different rules.
404
not-found
Unknown route or missing/foreign resource. Application reads also hide erasure.
405
method-not-allowed
Use the method documented for this path. OPTIONS has no body.
409
already-exists
externalRef belongs to another applicant email. Correct the data conflict.
410
failed-precondition
The application was erased; do not recreate it or grant access.
429
resource-exhausted
Honor Retry-After when supplied, otherwise use backoff with jitter.
5xx
internal or another published code
Use the HTTP status to decide retries; a 5xx can carry another published code. Reconcile writes before repeating them.
Rate limits and diagnostics
Budgets are 60 requests per minute per key and 240 per minute per source IP. The IP limit is applied before authentication. Coordinate workers sharing a key or egress IP and use these response headers:
Header
Meaning
Aegis-Request-Id
Opaque ID on every response emitted by the current handler, including errors and OPTIONS.
RateLimit-Limit
Per-key budget, normally 60.
RateLimit-Remaining
Requests remaining in that per-key window.
RateLimit-Reset
Seconds until reset, not an epoch timestamp.
Retry-After
Seconds to wait on per-key 429; matches the reset delay.
Pre-authentication IP refusals have no rate-limit or Retry-After headers. Unauthenticated responses and requests where no limiter window could be read also omit per-key headers. Missing headers do not mean unlimited requests. Log HTTP status, request ID and your own record ID, while redacting credentials, loginUrl and applicant data.
GET /v1/applications
Find an application by externalRef or retrieve applications changed since your last reconciliation. Required scope: applications:read. Send query parameters and no body.
Field
Type
Description
limit
integer
Page size, from 1 to 100. Default: 25.
cursor
string
Opaque nextCursor from the previous response. Omit on the first request. Do not construct or decode it.
status
string
One application status: pending, hold, needs_info, pending_approval, active or rejected.
externalRef
string
Exact match for your application reference. URL-encode the value.
updatedSince
string
RFC 3339 timestamp for a change-reconciliation window.
Example request
GET /v1/applications?limit=25&status=needs_info&updatedSince=2026-09-01T00:00:00.000Z
Authorization: Bearer aegis_<key-id>_<secret>
Applications matching the query. Read an individual application by clientId for its decision, open request summary and members.
nextCursor
string | null
Token for the next page. Null on the final page.
hasMore
boolean
True when another page exists. No total count is returned.
Results sort by updatedAt descending, then application ID descending. Keep filters fixed while paging. Unknown filters, invalid cursors and limits outside 1 to 100 return 400 invalid-argument. Records can change during a sweep: deduplicate by clientId and overlap the next updatedSince window. Save a recovery checkpoint only after processing all pages.
GET /v1/applications/{clientId}/decisions
Retrieve the application's decision history with applications:read and the clientId returned by provisioning. Send no body. Decisions describe the action, status transition, actor role, applicant-visible comment and decision time. Staff identity and internal assessment details are excluded. For the latest decision alongside current status, use GET application.
Request
GET /v1/applications/{clientId}/decisions
Authorization: Bearer aegis_<key-id>_<secret>
GET /v1/applications/{clientId}/checklist
Retrieve the document checklist for an application using applications:read. The checklist describes the evidence required by the intake and whether those requirements are satisfied. Send the application clientId in the path and no body. Direct applicants to the portal to supply missing evidence.
Request
GET /v1/applications/{clientId}/checklist
Authorization: Bearer aegis_<key-id>_<secret>
GET /v1/applications/{clientId}/documents
Retrieve document metadata using applications:read. Send the application clientId in the path and no body. The response does not transfer document contents, extracted personal data or signed download URLs. Document upload and review take place in the portal and dashboard.
Request
GET /v1/applications/{clientId}/documents
Authorization: Bearer aegis_<key-id>_<secret>
Keep application, request and event identifiers separate
Identifier
Use
externalRef
Your permanent application reference. Keep it stable throughout the case.
clientId
Aegis application ID. Use it in application paths and reconciliation.
Idempotency-Key
Your identifier for one write intent. Reuse it only for retries of that same operation, never for different request data.
Aegis-Request-Id
Server-generated HTTP request diagnostic ID. Use it with support, not as an application identity.
Webhook id / idempotencyKey
Identity of one event, stable across delivery attempts. Deduplicate on this value.
Information-request requestId
Identity of an information request and its response rounds. Unrelated to the HTTP diagnostic ID.
Portal and staff operations
The tenant API does not approve or reject cases, override risk, run staff screening, erase applicants, cancel applications or answer information requests on an applicant's behalf. Answers, forms and uploads stay in the portal; compliance decisions stay in the dashboard. Internal Firebase callables are not tenant REST endpoints. There is no separate GET members route; membership rides on the application read.
Versioning
The path version is v1, and webhook envelopes carry apiVersion. Accept additive response fields and handle unfamiliar status or event values without treating them as approval. Monitor the changelog for contract changes.