# Exercise: Create an API Endpoint

This exercise creates a tiny saga and exposes it as an API endpoint. You will run it through the **Train RPC** runner. The flow uses only three steps: `Start` → `Transform` → `Success`.

### Before you start

* You can access the **Devops** app and the **Saga** screen.
* The training deployment (including `train_rpc`) is installed and running.
* You know your API base URL: `https://[YOUR_ADMIN_API_DOMAIN]`.

### What you’ll build

* **Saga path**: `/HelloWorld`
* **Runner**: `train_rpc` (via **Allowed For: Train RPC**)
* **Response**: HTTP `200` with body `{message: "Hello World"}`

{% stepper %}
{% step %}

### Open the Saga screen

Open the [Saga](https://docs.rierino.com/devops/api-flows) screen from the [Devops](https://docs.rierino.com/devops) app.

Unless you changed routing, the UI is at `https://[YOUR_ADMIN_UI_DOMAIN]/app/devops/common/saga`.

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2FiPyYm2gvv1uUZBmw2EOQ%2FHello_World_Saga_Open.png?alt=media&#x26;token=51d51440-50c1-4416-bfe7-2430cf777853" alt=""><figcaption><p>Saga Screen</p></figcaption></figure>
{% endstep %}

{% step %}

### Create a new saga

Click **CREATE NEW** in the left menu area. This clears the editor and opens a blank saga.

You’ll define the saga metadata first. Then you’ll design the step graph.

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2FZeoPQEpR0FiqpkdSSSYf%2FCreate_Button.png?alt=media&#x26;token=29cdcc0e-06c2-42bd-b778-da3fa8ead0f2" alt=""><figcaption><p>Create New Button</p></figcaption></figure>
{% endstep %}

{% step %}

### Assign an ID

Click the pencil next to **ID:** and set a unique identifier.

For this exercise, use: `hello_world-0001`.

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2FIxNDRxUBUj1mR610v4K6%2FHello_World_Saga_ID.png?alt=media&#x26;token=8d04ccc2-84f1-46d2-b255-d2a5266ba574" alt=""><figcaption><p>Saga ID Assignment</p></figcaption></figure>

<details>

<summary>ID conventions (optional)</summary>

IDs can be auto-generated if an ID generator is configured. For core assets like sagas and queries, human-readable IDs make debugging and audits much easier.

{% hint style="info" %}
If you assign IDs manually, prefer alphanumerics plus `-` and `_`. For high-volume assets, consider a 4‑digit partition suffix (like `-0001`). For low-volume assets, you can skip partitioning.
{% endhint %}

</details>
{% endstep %}

{% step %}

### Define the saga (name, path, allowed runner)

Click the **Definition** icon (circled edit icon) to open saga metadata.

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2F98jR4XLwK2Ryag7O2G25%2FHello_World_Saga_Define_Open.png?alt=media&#x26;token=9473a3a0-8c17-4299-8a8d-be329b84f1f1" alt=""><figcaption><p>Definition Button</p></figcaption></figure>

Fill in these fields:

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2Fv9dg2M8x0xqAqxhN83Js%2Fimage.png?alt=media&#x26;token=c25c44ff-2e70-48b1-bd0d-463a270d46e1" alt=""><figcaption><p>Hello World Saga</p></figcaption></figure>

* **Saga Name:** `Hello World`
* **Saga Domain (optional):** `util`
* **Status:** `ACTIVE`
* **Saga Description (optional):** `Returns "Hello World"`
* **Saga Path:** `/HelloWorld`
* **Version:** `0`
* **Allowed For:** `Train RPC`
* **Auto Fail:** `true`

This means requests to `/HelloWorld` routed through `train_rpc` will execute this saga.

{% hint style="info" %}
**Allowed For** limits which runner can execute the saga. Leaving it empty allows any runner to execute it.
{% endhint %}
{% endstep %}

{% step %}

### Add steps (Start → Transform → Success)

Drag a **Start** step from the stencil.

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2FctZmb2wNCcXkznjJu6SE%2FHello_World_Saga_Start_Step.png?alt=media&#x26;token=87e2378e-bf1a-4644-934d-eccf1f9f8a75" alt=""><figcaption><p>Saga Stencil</p></figcaption></figure>

Drag a **Transform** step and a **Success** step.

Your canvas should look like this:

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2FBj1QL1DDlQaR2uwuGUW5%2FHello_World_Saga_All_Steps.png?alt=media&#x26;token=88890d6f-5cc2-45b8-b74b-1e08bdd03b7b" alt=""><figcaption><p>Saga Steps</p></figcaption></figure>

Connect `Start` → `Transform`.

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2FI0Akod4vSBytdEP3eknm%2FHello_World_Saga_Link.png?alt=media&#x26;token=cbf94a0e-0f34-4d1c-8140-5eda1f0fe486" alt=""><figcaption><p>Saga Link</p></figcaption></figure>

Connect `Transform` → `Success`.

Your graph should look like this:

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2Fy1ztFAk0h3JEGFneeprX%2FHello_World_Saga_Links.png?alt=media&#x26;token=9fce5728-be41-4787-8c70-e1cd1cbebfdf" alt=""><figcaption><p>Saga Links</p></figcaption></figure>
{% endstep %}

{% step %}

### Configure the Transform step

The flow runs now, but it does not yet return `"Hello World"`. You’ll add a static value to the payload.

Select the [Transform](https://docs.rierino.com/devops/api-flows/configuring-saga-steps/transform-step) step. Click its pencil icon to edit.

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2FYQ2BjftZRi9zZJSmCkVi%2FHello_World_Saga_Transform_Icon.png?alt=media&#x26;token=48a5561b-6709-4e57-b620-aa4a4d0a5eab" alt=""><figcaption><p>Transform Step Icons</p></figcaption></figure>

Set these values:

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2FHIUsjHsz5YtbCsF99yW7%2FHello_World_Saga_Transform_Define.png?alt=media&#x26;token=aaf6732d-1f80-4a3d-802b-7476cce6e8d0" alt=""><figcaption><p>Transform Definition Screen</p></figcaption></figure>

* **Step Name:** `Say Hello World`
* **Step Description (optional):** `This step adds a static "Hello World" message.`
* **Transform Class:** `Add Value to Payload`
* **Transform Parameters:**
  * **Key:** `value`
  * **Value:** `{message: "Hello World"}`

Click **Apply** to save the step configuration.

{% hint style="info" %}
**Why does Transform have a “Class”?**

Instead of adding a separate stencil shape for every transformation type, the step stays the same. You switch behavior by selecting a different **Class** (or **Action**) in the step config.

This makes it safer to evolve flows over time. You can change behavior without rebuilding the graph and breaking tracing continuity.
{% endhint %}

The step label should update on the canvas:

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2FRpfYtr1nNOqilDIrLhpb%2FHello_World_Saga_Transform_Set.png?alt=media&#x26;token=6508fc49-adff-401e-bd2c-cbb3eccfb545" alt=""><figcaption><p>Defined Transform Step</p></figcaption></figure>
{% endstep %}

{% step %}

### Save the saga

Click **SAVE** in the top-right corner.

<figure><img src="https://1659095931-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcnDk3J1AzTgg2NFrGPlh%2Fuploads%2FTVvANBKIxjoHru9QzTD8%2FSave_Button.png?alt=media&#x26;token=d715d553-2f8e-4464-966e-12a3738d0e08" alt=""><figcaption><p>Save Button</p></figcaption></figure>

Wait for the runner to pick up changes. In most training setups this is quick. If your environment has a reload interval, give it \~10–30 seconds.

You should see a confirmation notification.
{% endstep %}

{% step %}

### Test the endpoint

Call the API endpoint from your REST client:

`https://[YOUR_ADMIN_API_DOMAIN]/api/request/train_rpc/HelloWorld`

Expected result:

* HTTP `200 OK`
* Body: `{message: "Hello World"}`

{% hint style="info" %}
Remember the saga path is case-sensitive. Use `/HelloWorld` exactly as configured.
{% endhint %}
{% endstep %}
{% endstepper %}

### Troubleshooting

* **404 Not Found**: confirm **Saga Path** and that you saved the saga. Also confirm it’s allowed for **Train RPC**.
* **403/401**: gateway auth is blocking the request. Check your token/session.
* **Saga does not trigger**: confirm the request is routed through `train_rpc` (URL contains `/train_rpc/`).


---

# Agent Instructions: Querying This Documentation

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rierino.com/examples/training-examples/exercise-create-an-api-endpoint.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
