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

# Resolving actions

> Turn a collected action into a resolved one — the resolve, redirect, and report flow

# Resolving actions

Collecting a pending action tells you *what* needs to happen. This page covers the other half —
actually resolving it: starting the action, redirecting the end-user, and reporting the outcome so
the item clears.

<Note>
  Discover pending actions first with
  [Fetch the notification content](/partner-api/notifications/integration#5-fetch-the-notification-content)
  (webhook-driven) or
  [List what needs attention](/partner-api/user-journeys/end-user/notifications#list-what-needs-attention)
  (polling). Both hand you an action carrying the `resolution_link` this page acts on.
</Note>

## The resolution link

Every action is self-describing — you act on it without knowing the device type. You start from its
`resolution_link`:

```json theme={null}
"resolution_link": {
  "url": "/api/partners/v2.0/cues/{cue_id}/resolve?secret=<signed-secret>",
  "required_parameters": ["success_url", "cancel_url", "language"]
}
```

The `url` is relative (prefix `https://app.podero.com`) and already embeds the action's `cue_id` and
a signed `secret` — send it verbatim, never construct it yourself. Branch on the action's `code`; each
code names its own `required_parameters`.

<Note>
  The `secret` is bound to the notified user and **expires one hour after it is issued**. If it expires
  before the user acts, re-collect the action to obtain a fresh link.
</Note>

## Resolve a `reauthenticate` action

A `reauthenticate` action means a device's manufacturer connection has lapsed and optimization is
paused for it. Resolving it is a three-call flow.

<Steps>
  <Step title="Start the action">
    `POST` the `resolution_link.url`, supplying the fields named in `required_parameters`. This call
    needs **both** your bearer token **and** the signed `secret`.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST \
        'https://app.podero.com/api/partners/v2.0/cues/{cue_id}/resolve?secret=<signed-secret>' \
        -H 'Authorization: Bearer {access_token}' \
        -H 'Content-Type: application/json' \
        -d '{
          "success_url": "https://your-app.example.com/devices/reconnected",
          "cancel_url": "https://your-app.example.com/devices",
          "language": "de"
        }'
      ```
    </CodeGroup>

    | Field         | Required | Description                                                                                                                                     |
    | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
    | `success_url` | Yes      | Where the user lands after a successful reauthentication.                                                                                       |
    | `cancel_url`  | Yes      | Where the user lands if they cancel or it fails.                                                                                                |
    | `language`    | No       | IETF tag localising the flow: `sv`, `de`, `en`, `hu`, `it`, `et`, `pl`, `ro`, `hr`, `nl`. Omitted or unsupported falls back to the org default. |

    The response carries the manufacturer flow to send the user into:

    ```json theme={null}
    { "redirect_url": "https://connect.podero.com/inverters/instructions?onboarding_session_id=...&device=foxess" }
    ```
  </Step>

  <Step title="Redirect the end-user">
    Send the user to `redirect_url`. They re-authenticate with the manufacturer in Podero's hosted
    flow, then land back on the `success_url` (or `cancel_url`) you supplied. The `redirect_url` is
    single-use and tied to this action — start a fresh action per user, don't cache it.
  </Step>

  <Step title="Report the outcome">
    From your `success_url` / `cancel_url` handler, report the result. This call is authenticated by
    the **`secret` alone** — no bearer token.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST \
        'https://app.podero.com/api/partners/v2.0/cues/{cue_id}/state?secret=<signed-secret>' \
        -H 'Content-Type: application/json' \
        -d '{ "state": "success" }'
      ```
    </CodeGroup>

    | `state`   | Effect                                                                                 |
    | --------- | -------------------------------------------------------------------------------------- |
    | `success` | Marks the action done. It drops out of the pending list and optimization resumes.      |
    | `fail`    | Records the failure but leaves the action available — retry from **Start the action**. |
  </Step>
</Steps>

## Resolve an `information` action

An `information` action is a notice to show the user (`metadata.message`), not a flow to walk. It has
**no `required_parameters`** and is resolved — dismissed — by a single call to its `resolution_link`,
with no body:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST \
    'https://app.podero.com/api/partners/v2.0/cues/{notification_id}/information/resolve?secret=<signed-secret>'
  ```
</CodeGroup>

The notice is marked read: it leaves the pending list and the `information_available` count, but stays
retrievable in history via
[`GET /notifications/information`](/partner-api/notifications/reference#list-information-notifications)
with `dismissed: true`.

## Lifecycle & semantics

Understanding the state machine behind an action keeps your integration correct under retries and
expiry.

```
raised ──▶ started ──▶ succeeded ──▶ done   (clears from the pending list)
              │
              └──────▶ failed ──▶ (still pending — retry from "Start")
```

<AccordionGroup>
  <Accordion title="Secrets expire after one hour" icon="clock">
    The `secret` inside every `resolution_link.url` is bound to the notified user and expires **one
    hour after it was issued**. Resolve promptly. If a call returns `404`, the secret has expired or
    the action is already resolved — re-collect the action to obtain a fresh `resolution_link`, then
    retry.
  </Accordion>

  <Accordion title="Reporting is idempotent" icon="rotate">
    Submitting `success` twice for the same action returns the same `action_id` and does not
    double-resolve. Safe to retry the report call after a network error.
  </Accordion>

  <Accordion title="Failure keeps the action open" icon="arrow-rotate-left">
    Reporting `fail` records the attempt but leaves the action pending, so the user can try again.
    Only `success` clears it.
  </Accordion>

  <Accordion title="Two auth models" icon="key">
    **Start** (`/resolve`) needs your bearer token **and** the `secret`. **Report** (`/state`) and
    the information **dismiss** need the `secret` **only** — the signed token is the authorization, so
    these can be called from a lightweight redirect handler without your API credentials.
  </Accordion>
</AccordionGroup>

## Forward compatibility

Every action is fully described by its own `code`, `resolution_link`, and `required_parameters`. Your
resolver branches on `code`, calls the `url` with the parameters it names, and reports the outcome —
no device-type-specific logic, no hand-built URLs. When Podero introduces a new action code, it flows
through the resolver you already wrote; you only add rendering for the new code.

## Next steps

<CardGroup cols={2}>
  <Card title="Notifications journey" icon="list-check" href="/partner-api/user-journeys/end-user/notifications">
    The end-user-facing walkthrough: badges, lists, and resolution in your app.
  </Card>

  <Card title="Reference" icon="code" href="/partner-api/notifications/reference">
    The message envelope, topics, and the Notification Content API.
  </Card>
</CardGroup>
