> For the complete documentation index, see [llms.txt](https://docs.osmosworks.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.osmosworks.com/overview-and-core-concepts/end-to-end-lifecycle.md).

# End-to-end request lifecycle

This page follows a realistic example through Osmos from organization setup to application completion.

## Example: family visa assistance

A new tenant, **Acme Immigration Services**, configures a **Family Visa Assistance** service. A customer, **Chinua Traveller**, submits a request and completes the process.

### Lifecycle sequence diagram

```mermaid
sequenceDiagram
    autonumber
    actor Customer as Customer (Chinua)
    actor Staff as Staff / Admin (Ada)
    participant Osmos as Osmos Backend
    participant Cloud as Cloudinary
    participant Pay as Paystack
    participant DB as PostgreSQL

    Note over Customer,Osmos: 1. Draft Request & Submission
    Customer->>Osmos: POST /customer/requests/{serviceId}
    Osmos->>DB: Create ServiceRequest (DRAFT)
    Customer->>Osmos: POST /files (Authorize upload)
    Osmos-->>Customer: Return signed upload params
    Customer->>Cloud: POST direct upload file
    Cloud->>Osmos: Webhook: confirm upload -> FileObject (UPLOADED)
    Customer->>Osmos: PUT answers & link uploaded document
    Customer->>Osmos: POST /customer/requests/{id}/submit
    Osmos->>DB: Validate required fields -> Status: PENDING

    Note over Staff,Osmos: 2. Review & Acceptance
    Staff->>Osmos: POST /staff/requests/{id}/accept
    Osmos->>DB: Freeze ServiceSnapshot, copy stages & questions
    Osmos->>DB: Create Application (IN_PROGRESS), Stage 1 (CURRENT)
    Osmos->>DB: Mark Request ACCEPTED

    Note over Customer,Pay: 3. Stage Progression & Payment
    Staff->>Osmos: POST /staff/applications/{id}/stages/1/complete
    Osmos->>DB: Advance to Stage 2 (Payment Stage) -> Generate Invoice (OPEN)
    Customer->>Osmos: POST /public/payments/invoices/{ref}/checkout
    Osmos->>Pay: Initialize Paystack checkout
    Pay-->>Customer: Redirect to payment gateway
    Customer->>Pay: Complete card/bank payment
    Pay->>Osmos: POST /payments/webhook (charge.success)
    Osmos->>DB: Mark Invoice PAID & Advance Stage

    Note over Staff,Customer: 4. Final Completion
    Staff->>Osmos: POST /staff/applications/{id}/stages/{last}/complete
    Osmos->>DB: Mark Application COMPLETED
    Osmos-->>Customer: Application fulfilled
```

### 1. Organization registration

**Actor:** Prospective tenant admin (Ada) **API:** `POST /api/v1/organizations/register`

Ada provides her email, name, and password. The backend:

1. Normalizes the email and checks that no tenant admin already exists for it.
2. Creates a `TenantOnboarding` record.
3. Issues a setup token and records an outbox event for the verification email.
4. Sends a verification email with a link to `/onboarding/verify?token=...`.

### 2. Email verification

**Actor:** Ada **API:** `GET /api/v1/organizations/verify?token={token}`

Ada clicks the link. The backend:

1. Validates the token and marks the onboarding email as verified.
2. Generates an onboarding JWT and sets the `osmos_onboarding_token` cookie.
3. Returns verification details.

### 3. Workspace creation

**Actor:** Ada **API:** `POST /api/v1/organizations/create`

Ada provides the slug `acme-immigration`, organization name, sector, and expected volume. The backend:

1. Verifies the email is verified and the slug is available.
2. Creates the `Tenant`, `TenantProfile`, and `TenantSettings`.
3. Creates a `Principal` of type `TENANT_ADMIN` and a `TenantMember` for Ada.
4. Bootstraps the workspace with default roles and permissions.
5. Issues session cookies and a session handoff.
6. Publishes audit events.

### 4. Service configuration

**Actor:** Ada (tenant admin) **APIs:**

* `POST /api/v1/tenant/services`
* `POST /api/v1/tenant/services/{serviceId}/stages`
* `POST /api/v1/tenant/services/{serviceId}/questions`
* `POST /api/v1/tenant/services/{serviceId}/documents`
* `POST /api/v1/tenant/services/{serviceId}/charges`
* `POST /api/v1/tenant/services/{serviceId}/value-sets`
* `POST /api/v1/tenant/services/{serviceId}/publish`

Ada creates the **Family Visa Assistance** service with:

* Currency `NGN`, party role **Traveller**, min parties 1, max parties 6.
* Stage 1: **Traveller details** (ordinary)
  * Question `nationality` (single choice)
  * Question `travel_date` (date)
  * Requirement `passport_copy` (required, review required)
* Stage 2: **Add-ons** (ordinary)
  * Question `express_processing` (boolean)
* Stage 3: **Payment** (payment)
  * Charge `Base fee` (`PER_PARTY`)
  * Charge `Express fee` (`PER_REQUEST`, charge rule `request.express_processing == true`)
* Value set `ECOWAS` with member states.

Ada publishes the service. The backend verifies that every ordinary stage has a question and every payment stage has a charge.

### 5. Customer creates a draft request

**Actor:** Chinua (customer) **API:** `POST /api/v1/customer/requests/{serviceId}`

Chinua is logged in as a customer of Acme Immigration. The backend:

1. Verifies the service is published and not archived.
2. Checks that Chinua does not already have an open request for this service.
3. Finds or creates a self party for Chinua.
4. Creates a `ServiceRequest` with reference `REQ-000001` and status `DRAFT`.

### 6. Customer fills in answers and documents

**Actor:** Chinua **APIs:**

* `PUT /api/v1/customer/requests/{requestId}/answers/{questionId}`
* `PUT /api/v1/customer/requests/{requestId}/documents/{requirementId}`

Chinua uploads `passport.pdf` through the file upload flow (authorize, upload to Cloudinary, webhook confirmation) and attaches the file object to the passport requirement. He answers nationality and travel date.

### 7. Customer submits the request

**Actor:** Chinua **API:** `POST /api/v1/customer/requests/{requestId}/submit`

The backend validates:

* All visible required questions have answers.
* All visible required documents are uploaded.

The request status becomes `PENDING`.

### 8. Staff reviews and accepts the request

**Actor:** Ada or another staff member **APIs:**

* `GET /api/v1/staff/requests/{requestId}`
* `POST /api/v1/staff/requests/{requestId}/accept`

The backend:

1. Verifies the request is `PENDING`.
2. Creates an `Application` with a service snapshot.
3. Copies stages, questions, requirements, and draft answers into application-scoped tables.
4. Sets the first visible stage to `CURRENT`.
5. Marks the request `ACCEPTED`.

### 9. Application progression

**Actor:** Chinua and staff **APIs:**

* `PUT /api/v1/customer/applications/{applicationId}/answers/{questionId}`
* `PUT /api/v1/customer/applications/{applicationId}/documents/{requirementId}`
* `POST /api/v1/staff/applications/{applicationId}/stages/{stageId}/complete`

Chinua answers the `express_processing` question. Staff complete stage 1 and stage 2. When stage 3 (payment) becomes current, the backend creates an invoice from the charges.

### 10. Payment

**Actor:** Chinua **APIs:**

* `POST /api/v1/finance/invoices/{invoiceId}/payments` (or public checkout)
* Paystack webhook `POST /api/v1/payments/webhook`

Chinua pays the invoice through Paystack. The webhook is verified and processed asynchronously. On success:

1. The payment is marked `SUCCESSFUL`.
2. The invoice is marked `PAID`.
3. The application payment stage is marked paid.
4. The application advances or completes.

### 11. Completion

**Actor:** Staff **API:** `POST /api/v1/staff/applications/{applicationId}/stages/{stageId}/complete`

After the payment stage is complete, there are no further visible stages. The application status becomes `COMPLETED`.

## How exceptions affect progression

| Situation                           | Effect                                                                                       |
| ----------------------------------- | -------------------------------------------------------------------------------------------- |
| Missing required answer at submit   | Request cannot be submitted; customer receives `APPLICATION_MISSING_REQUIRED_ANSWERS`.       |
| Missing required document at submit | Request cannot be submitted; customer receives `APPLICATION_MISSING_REQUIRED_DOCUMENTS`.     |
| Staff reject request                | Request status becomes `REJECTED`; no application is created.                                |
| Payment fails or is abandoned       | Payment stage remains `CURRENT`; staff can trigger reconciliation or the customer can retry. |
| Invoice amount mismatch             | Payment is not fulfilled; invoice remains open.                                              |
| Party count changed after payment   | Rejected with `APPLICATION_PARTY_COUNT_LOCKED`.                                              |

## Another sector example: school admission

The same flow applies to other sectors. For example, a school admission service could have:

* Party role: **Student**
* Stage 1: Student details and parent/guardian information.
* Stage 2: Document requirements (birth certificate, transcripts).
* Stage 3: Payment of application fee.

The backend supports this configuration as long as the service definition uses the same building blocks: stages, questions, requirements, and charges.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.osmosworks.com/overview-and-core-concepts/end-to-end-lifecycle.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
