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

# Callbacks and redirects

> How to receive status-change callbacks, regenerate one-time signing links, suppress NSEV's own notifications, and redirect users after they act.

When a package moves through its signing flow, you usually want two things: your own system to
be told when something changes, and the end user to be sent somewhere sensible after they act.
NSEV gives you several mechanisms for this, set when you create the package or when you create an
actor. This page explains what each one is, when it fires, and how to use it.

The mechanisms fall into two groups:

* **Callbacks** - server-to-server HTTP POSTs from NSEV to your system (`CallBackUrl`,
  `NotificationCallBackUrl`).
* **Redirects** - where the end user's browser is sent after they finish (`RedirectUrl`,
  `DefaultRedirectUrl`, `F2fRedirectUrl`, controlled by `RedirectType`).

Plus `SuppressNotifications`, which turns off the emails NSEV would otherwise send to an actor.

***

## CallBackUrl - status-change callbacks

`CallBackUrl` is a package-level property. When you set it on the package, NSEV sends an HTTP
`POST` to that URL whenever the package's status changes, so an external system can react.

**When it fires.** A callback is sent on end-user actions, including:

* a user changes the package from `Draft` to `Pending`, or revokes it, in the Document Portal
* a user clicks confirm in a drag-and-drop editor window
* a signer completes all their signing fields
* all signers have signed the package
* a signer rejects the package
* an approver approves the package
* form fillers complete their fields
* the system sets the package to `Failed`

<Note>
  API requests never trigger a callback. Callbacks fire only when an end user triggers an action in
  the NSEV WebPortal or Signer application. More triggers may be added in future versions.
</Note>

**The payload.** The `POST` body is `application/json` containing `packageId` and `packageStatus`:

```json theme={null}
{ "packageId": "d2912916-c555-47af-b666-1e8cf2eb9dfa", "packageStatus": "Finished" }
```

If your system needs more than the status, call `GET /packages/{packageId}` to fetch the full
package.

**How to use it well.**

* The `CallBackUrl` must be a valid, absolute URL with no query parameters.
* The callback has a **100-second timeout**. If your service does not respond in time, NSEV forces
  the timeout and finishes the flow as if it had received `200 OK`. Respond as quickly as possible
  and run any follow-up work asynchronously, so your processing never blocks the signing flow.
* On error, NSEV retries the callback **3 times over 3 retry cycles** by default. Administrators
  can customize the retry mechanism.

***

## NotificationCallBackUrl - regenerating one-time signing links

NSEV uses **one-time signing URLs**: once an action link is clicked it expires, and a new link must
be requested. `NotificationCallBackUrl` is a package-level property that, when set, calls your
remote service each time a signer requests a new link - instead of NSEV sending its usual email.
Your service then decides what to do (for example, deliver the new link through your own channel).

**When it fires.** Unlike `CallBackUrl`, which fires on major state changes, the notification
callback can fire repeatedly without an apparent status change - so the payload tells you which
kind of notification was requested. The remote service is called **once per user action**, with no
retry unless the end user requests another notification.

**The payload.** An `application/json` `POST` body containing:

| Field                 | Description                                  |
| --------------------- | -------------------------------------------- |
| `packageId`           | Unique identifier of the package             |
| `actorId`             | The actor the notification was triggered for |
| `language`            | The language the end user was told to use    |
| `notificationTypeKey` | Which kind of notification was requested     |

Current `notificationTypeKey` values:

| `notificationTypeKey` | Meaning                                                                                                           |
| --------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `SendActionUrl`       | The single-use action link (form filler, approver, signer) was already used and the end user requested a new one. |
| `SendDownloadUrl`     | The single-use download link was already used and the end user requested a new one.                               |

<Warning>
  This list may grow. Your service must ignore `notificationTypeKey` values it does not recognize
  without returning an error response.
</Warning>

NSEV waits for your service to finish before returning control to the end user, so it must respond
within seconds. On error, NSEV retries 3 times over 3 retry cycles by default.

<Note>
  `NotificationCallBackUrl` is separate from `SuppressNotifications`. The emails NSEV sends when a
  package is created, revoked, and so on are governed by `SuppressNotifications`, not by the
  notification callback.
</Note>

***

## SuppressNotifications - deliver links yourself

`SuppressNotifications` is an **actor-level** property (default `false`). When set to `true` on an
actor, NSEV does not send that actor the emails it would normally send about the package.

This is the basis of the **technical-user pattern**: rather than letting NSEV email your signers
directly, you suppress its notifications and deliver the signing links yourself - through your own
application, email, or portal. Pair it with `NotificationCallBackUrl` so that when a one-time link
expires and the user requests a new one, your system is called to deliver the replacement instead
of NSEV sending an email.

<Note>
  Automatic reminders and expiration reminders are not affected by `SuppressNotifications`: an actor
  with `SuppressNotifications` set to `true` still receives automatic reminders and the expiration
  reminder if those are configured on the package.
</Note>

***

## RedirectUrl - where a user goes after acting

`RedirectUrl` is an **actor-level** property. When a Signer or FormFiller finishes their action,
their browser is redirected to this URL. If no `RedirectUrl` is set, the end user has to close the
browser tab themselves.

NSEV appends query parameters to the URL so your return endpoint knows what happened:

* `SessionID` - the package signing session (the actor's `ActorId`)
* `ExternalReference` - the stakeholder's `ExternalReference`
* `Status` - `FINISHED`, `REJECTED`, or `INVALIDTOKEN`
* `PackageExternalReference` - the package's `ExternalReference`

For this to be useful, set meaningful `ExternalReference` values on your packages and stakeholders;
see [The package model → ExternalReference](/docs/nsev/build/concepts/package-model#externalreference).

<Warning>
  The redirect happens **client-side**, so the end user can counterfeit the returned `Status`. Never
  trust the redirect alone to confirm signing. Verify the outcome through a second secure channel -
  the `CallBackUrl` - or by checking session state, and then confirm with a
  `GET /packages/{packageId}/status` call.
</Warning>

`RedirectUrl` must be a valid, absolute URL with no existing query parameters.

### DefaultRedirectUrl - a package-wide fallback

`DefaultRedirectUrl` is a **package-level** property. It sets the
URL stakeholders are redirected to after completing their actions when an actor has no `RedirectUrl`
of its own. It is applied on package submit. Use it to set one fallback redirect for the whole
package instead of repeating the same `RedirectUrl` on every actor.

### RedirectType - when the redirect fires

`RedirectType` is an **actor-level** property that controls *when* the redirect happens. It applies
only to **Signer** and **FormFiller** actors, and is only valid together with a `RedirectUrl` - the
API rejects a `RedirectType` set without one. The possible values are:

| Value                    | Behaviour                                                                                                                                                                                                            |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AfterSession` (default) | The user is redirected after the signing or form-filling session ends, but before the package is completed. They cannot close the session early and must wait for all their fields to be filled or documents signed. |
| `Immediately`            | The user is redirected as soon as possible.                                                                                                                                                                          |
| `AfterDelay`             | The user is redirected after a short delay.                                                                                                                                                                          |
| `AfterCompletion`        | The user is redirected only after the entire package is completed. When set for multiple actors, it applies only to the final actor; the others fall back to `AfterSession`.                                         |

<Note>
  `RedirectType` is exposed only on Signer and FormFiller actors in the API - not on Approver or
  Receiver actors.
</Note>

***

## F2fRedirectUrl - face-to-face signing only

`F2fRedirectUrl` is a **package-level** property for **face-to-face signing in the Document
Portal** only. The end user is redirected to it after all fields have been signed or rejected face
to face. Do not confuse it with the regular `RedirectUrl` - `F2fRedirectUrl` applies only to
face-to-face signing, not to remote signing sessions.

NSEV appends these query parameters:

* `SessionID` - the package signing session (the package's ID)
* `Status` - `FINISHED`, `REJECTED`, or `INVALIDTOKEN`
* `PackageExternalReference` - the package's `ExternalReference`

<Warning>
  As with `RedirectUrl`, the F2F redirect happens client-side and can be counterfeited. Confirm the
  outcome through the `CallBackUrl` or session state, then verify with a `GET /packages/{packageId}/status`
  call.
</Warning>

`F2fRedirectUrl` must be a valid, absolute URL with no existing query parameters.

**Close-button interaction.** During asynchronous signing, a signer can normally use a **Close**
button to leave while signing continues in the background. When an `F2fRedirectUrl` is configured,
that Close button is unavailable; instead the signer sees a message telling them they will be
redirected once signing finishes.

***

## Polling versus callbacks

There are two ways to find out when a package has progressed:

* **Callbacks (recommended for integrations).** Set a `CallBackUrl` and let NSEV notify your system
  on each status change. This avoids repeated polling, reacts immediately, and scales better. Make
  sure your callback endpoint responds fast and does its real work asynchronously (remember the
  100-second timeout).
* **Polling (fine for simple flows).** Call `GET /packages/{packageId}/status` periodically until
  the package reaches a terminal status such as `Finished`. This is simpler to build and is a
  reasonable choice for low-volume or one-off flows where you do not want to expose a public
  callback endpoint.

The [Send a document for signing](/docs/nsev/build/tutorials/send-for-signing) tutorial
uses polling for simplicity; switching that final step to a `CallBackUrl` is the recommended
approach for a production integration.
