> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flowmaticai.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Flowmatic Quickstart: Build Your First Workflow in 7 Steps

> Follow seven steps to register, verify your email, upload a CSV, build a filter workflow, trigger a run, and check results with the Flowmatic API.

This guide walks you through everything you need to send your first automated email campaign with Flowmatic. By the end you will have a registered account, an uploaded CSV dataset, a live workflow, and a completed run — all through the REST API. No dashboard required, no AI key needed for this example. The entire sequence takes under 10 minutes.

<Note>
  All examples below use `https://api.flowmatic.io` as the base URL. Replace this with your environment's base URL if you are using a self-hosted or staging instance.
</Note>

<Steps>
  <Step title="Register an account">
    Create your Flowmatic account by sending a `POST` request to `/api/auth/register`. Provide your email address, a password, and your full name. On success, Flowmatic sends a one-time passcode (OTP) to the email address you registered — you will need it in the next step.

    <ParamField body="email" type="string" required>
      The email address you want to associate with your Flowmatic account. This address will also receive workflow delivery receipts.
    </ParamField>

    <ParamField body="password" type="string" required>
      Your account password. Must be at least 8 characters. Store this securely — Flowmatic never exposes it again after creation.
    </ParamField>

    <ParamField body="fullName" type="string" required>
      Your full name. Used in account communications and the dashboard.
    </ParamField>

    ```bash theme={null}
    curl -X POST https://api.flowmatic.io/api/auth/register \
      -H "Content-Type: application/json" \
      -d '{
        "email": "you@example.com",
        "password": "supersecret123",
        "fullName": "Jane Smith"
      }'
    ```

    A successful registration returns HTTP 201:

    ```json theme={null}
    {
      "message": "Registration successful. Please check your email for a verification code."
    }
    ```

    <Note>
      If you do not receive the OTP within a couple of minutes, check your spam folder. You can also request a fresh code in Step 2b using the resend endpoint.
    </Note>
  </Step>

  <Step title="Verify your email address">
    Flowmatic requires email verification before your account is active. Submit the OTP that was sent to your inbox along with your email address. On success, Flowmatic returns an `accessToken` and a `refreshToken` — you can start making authenticated requests immediately.

    <ParamField body="email" type="string" required>
      The same email address you registered with.
    </ParamField>

    <ParamField body="otp" type="string" required>
      The six-digit one-time passcode delivered to your inbox.
    </ParamField>

    ```bash theme={null}
    curl -X POST https://api.flowmatic.io/api/auth/verify-email \
      -H "Content-Type: application/json" \
      -d '{
        "email": "you@example.com",
        "otp": "847291"
      }'
    ```

    A successful verification returns HTTP 200 with your tokens:

    ```json theme={null}
    {
      "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."
    }
    ```

    **Didn't receive the code?** Resend it with a single call:

    ```bash theme={null}
    curl -X POST https://api.flowmatic.io/api/auth/resend-otp \
      -H "Content-Type: application/json" \
      -d '{ "email": "you@example.com" }'
    ```
  </Step>

  <Step title="Log in and retrieve your access token">
    After your first verification you already have tokens, but for any subsequent session you will need to log in. Use `POST /api/auth/login` to receive a fresh JWT `accessToken` and `refreshToken`. You will attach the `accessToken` to every subsequent API request via the `Authorization` header.

    <ParamField body="email" type="string" required>
      Your registered email address.
    </ParamField>

    <ParamField body="password" type="string" required>
      Your account password.
    </ParamField>

    ```bash theme={null}
    curl -X POST https://api.flowmatic.io/api/auth/login \
      -H "Content-Type: application/json" \
      -d '{
        "email": "you@example.com",
        "password": "supersecret123"
      }'
    ```

    A successful login returns HTTP 200 with both tokens:

    ```json theme={null}
    {
      "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
      "expiresIn": 3600
    }
    ```

    <Tip>
      Save both tokens. The `accessToken` expires after the number of seconds in `expiresIn`. When it expires, exchange your `refreshToken` at `POST /api/auth/refresh-token` to obtain a new one without logging in again. See the [Authentication guide](/authentication) for details.
    </Tip>

    For the remaining steps, export your token as a shell variable to keep the examples concise:

    ```bash theme={null}
    export TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
    ```
  </Step>

  <Step title="Upload a CSV file">
    Flowmatic reads your audience data from an uploaded CSV. Send the file as `multipart/form-data` with a single field named `file`. The response returns an `uploadId` that you will reference inside your workflow graph.

    Your CSV should have a header row. For this quickstart, use a file with at least the columns `email`, `name`, and `rating`:

    ```
    email,name,rating
    alice@example.com,Alice,5
    bob@example.com,Bob,3
    carol@example.com,Carol,5
    dave@example.com,Dave,4
    ```

    Save this as `audience.csv`, then upload it:

    ```bash theme={null}
    curl -X POST https://api.flowmatic.io/api/uploads \
      -H "Authorization: Bearer $TOKEN" \
      -F "file=@audience.csv"
    ```

    A successful upload returns HTTP 201:

    ```json theme={null}
    {
      "uploadId": "upl_01hx9bk2vf3qkzm7p4cnjdt6ew",
      "filename": "audience.csv",
      "rows": 4,
      "columns": ["email", "name", "rating"],
      "createdAt": "2024-05-10T12:00:00Z"
    }
    ```

    <Note>
      Copy the `uploadId` — you will paste it into the workflow body in the next step.
    </Note>

    <ResponseField name="uploadId" type="string">
      The unique identifier for this upload. Pass this as `data.uploadId` in a `DATA_SOURCE` node.
    </ResponseField>

    <ResponseField name="rows" type="integer">
      The number of data rows Flowmatic parsed from the CSV (excluding the header).
    </ResponseField>

    <ResponseField name="columns" type="string[]">
      The column names detected from the CSV header row.
    </ResponseField>
  </Step>

  <Step title="Create your first workflow">
    Now define the automation as a graph. This example targets everyone in your CSV who gave a rating greater than 4 and sends them a thank-you email — no AI key required, just a `FILTER` node.

    Replace `<your-upload-id>` in the body below with the `uploadId` from the previous step.

    <ParamField body="name" type="string" required>
      A human-readable name for the workflow. Visible in the dashboard and run logs.
    </ParamField>

    <ParamField body="graph" type="object" required>
      The workflow graph definition containing `nodes` (array) and `edges` (array).
    </ParamField>

    <ParamField body="graph.nodes" type="array" required>
      An array of node objects. Each node must have a unique `id`, a `type`, and a `data` object.
    </ParamField>

    <ParamField body="graph.edges" type="array" required>
      An array of edge objects. Each edge must have a `source` node `id` and a `target` node `id`.
    </ParamField>

    ```bash theme={null}
    curl -X POST https://api.flowmatic.io/api/workflows \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Email 5-star raters",
        "graph": {
          "nodes": [
            { "id": "t",   "type": "TRIGGER",     "data": {} },
            { "id": "ds",  "type": "DATA_SOURCE",  "data": { "uploadId": "<your-upload-id>" } },
            { "id": "f",   "type": "FILTER",       "data": { "source": "{{ds.rows}}", "expr": "rating > 4" } },
            { "id": "out", "type": "OUTPUT",        "data": {
                "forEach": "{{f.items}}",
                "to":      "{{item.email}}",
                "subject": "Thanks {{item.name}}",
                "body":    "Hi {{item.name}}, thanks for the 5-star review!"
            }}
          ],
          "edges": [
            { "source": "t",  "target": "ds" },
            { "source": "ds", "target": "f"  },
            { "source": "f",  "target": "out"}
          ]
        }
      }'
    ```

    A successful creation returns HTTP 201:

    ```json theme={null}
    {
      "workflowId": "wfl_01hx9cm3ag4rlzn8q5doke7fpx",
      "name": "Email 5-star raters",
      "createdAt": "2024-05-10T12:01:00Z"
    }
    ```

    <ResponseField name="workflowId" type="string">
      The unique identifier for the newly created workflow. You will use this to trigger runs.
    </ResponseField>

    Here is what each node does in this graph:

    | Node ID | Type         | Role                                                     |
    | ------- | ------------ | -------------------------------------------------------- |
    | `t`     | TRIGGER      | Starts execution                                         |
    | `ds`    | DATA\_SOURCE | Loads rows from your uploaded CSV                        |
    | `f`     | FILTER       | Keeps only rows where `rating > 4`                       |
    | `out`   | OUTPUT       | Sends a personalised thank-you email to each matched row |
  </Step>

  <Step title="Run the workflow">
    Trigger an execution of the workflow you just created. Flowmatic accepts the request immediately, schedules it asynchronously, and responds with HTTP 202 and a `runId`.

    ```bash theme={null}
    curl -X POST https://api.flowmatic.io/api/workflows/wfl_01hx9cm3ag4rlzn8q5doke7fpx/run \
      -H "Authorization: Bearer $TOKEN"
    ```

    Flowmatic responds with HTTP 202:

    ```json theme={null}
    {
      "runId": "run_01hx9cq7bh5smzp9r6entjk8gy",
      "status": "PENDING",
      "workflowId": "wfl_01hx9cm3ag4rlzn8q5doke7fpx",
      "triggeredAt": "2024-05-10T12:02:00Z"
    }
    ```

    <ResponseField name="runId" type="string">
      The unique identifier for this run. Use it to poll for status in the next step.
    </ResponseField>

    <ResponseField name="status" type="string">
      Initial status. Always `PENDING` immediately after submission.
    </ResponseField>

    <Note>
      HTTP 202 means "accepted, not yet complete." The run is queued and will begin executing momentarily. Do not re-submit if you receive 202 — your run is already in the queue.
    </Note>
  </Step>

  <Step title="Monitor the run">
    Poll the run status endpoint until the status transitions to `SUCCESS` or `FAILED`. For a four-row CSV with a simple filter, this typically takes just a few seconds.

    ```bash theme={null}
    curl -X GET https://api.flowmatic.io/api/workflows/runs/run_01hx9cq7bh5smzp9r6entjk8gy \
      -H "Authorization: Bearer $TOKEN"
    ```

    While the run is processing you will see:

    ```json theme={null}
    {
      "runId": "run_01hx9cq7bh5smzp9r6entjk8gy",
      "status": "RUNNING",
      "workflowId": "wfl_01hx9cm3ag4rlzn8q5doke7fpx",
      "triggeredAt": "2024-05-10T12:02:00Z",
      "startedAt": "2024-05-10T12:02:01Z"
    }
    ```

    Once complete, the response includes a `result` object with delivery statistics:

    ```json theme={null}
    {
      "runId": "run_01hx9cq7bh5smzp9r6entjk8gy",
      "status": "SUCCESS",
      "workflowId": "wfl_01hx9cm3ag4rlzn8q5doke7fpx",
      "triggeredAt": "2024-05-10T12:02:00Z",
      "startedAt":   "2024-05-10T12:02:01Z",
      "completedAt": "2024-05-10T12:02:04Z",
      "result": {
        "emailsSent": 2,
        "filteredOut": 2,
        "totalRows": 4
      }
    }
    ```

    <ResponseField name="status" type="string">
      One of `PENDING`, `RUNNING`, `SUCCESS`, or `FAILED`.
    </ResponseField>

    <ResponseField name="result.emailsSent" type="integer">
      The number of emails successfully dispatched by the OUTPUT node.
    </ResponseField>

    <ResponseField name="result.filteredOut" type="integer">
      The number of rows excluded by FILTER nodes.
    </ResponseField>

    <ResponseField name="result.totalRows" type="integer">
      The total number of rows that entered the graph from the DATA\_SOURCE node.
    </ResponseField>

    In this example, 2 out of 4 rows had `rating > 4` (Alice and Carol), so `emailsSent` is 2 and `filteredOut` is 2. Your first Flowmatic workflow is complete!

    <Tip>
      For production integrations, consider polling with exponential backoff (e.g. 1 s, 2 s, 4 s, …) rather than a tight loop to avoid burning through rate limits while waiting on longer AI-powered runs.
    </Tip>
  </Step>
</Steps>

## Complete Workflow Example

For reference, here is the full workflow creation body used in Step 5 — ready to copy and paste with your own `uploadId`:

```json theme={null}
{
  "name": "Email 5-star raters",
  "graph": {
    "nodes": [
      { "id": "t",  "type": "TRIGGER",     "data": {} },
      { "id": "ds", "type": "DATA_SOURCE", "data": { "uploadId": "<your-upload-id>" } },
      { "id": "f",  "type": "FILTER",      "data": { "source": "{{ds.rows}}", "expr": "rating > 4" } },
      { "id": "out", "type": "OUTPUT", "data": {
          "forEach": "{{f.items}}",
          "to": "{{item.email}}",
          "subject": "Thanks {{item.name}}",
          "body": "Hi {{item.name}}, thanks for the 5-star review!"
      }}
    ],
    "edges": [
      { "source": "t",  "target": "ds" },
      { "source": "ds", "target": "f" },
      { "source": "f",  "target": "out" }
    ]
  }
}
```

## Next Steps

Now that you have run your first workflow, explore the features that make Flowmatic powerful for production use cases.

<CardGroup cols={2}>
  <Card title="Authentication" icon="lock" href="/authentication">
    Understand token refresh, expiry, and how to keep your integration authenticated long-term.
  </Card>

  <Card title="AI Nodes" icon="sparkles" href="/concepts/nodes">
    Add LLM-powered transformations to personalise emails at scale.
  </Card>

  <Card title="Google Drive" icon="google-drive" href="/guides/google-drive-integration">
    Connect a Google Sheet as a live data source so every run pulls fresh data automatically.
  </Card>

  <Card title="Workflow Runs API" icon="chart-line" href="/api-reference/runs">
    Explore the full runs API including listing historical runs and streaming logs.
  </Card>
</CardGroup>
