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

# signup_requested: Plan and sign-up

> Configure GamiFest email sign-up, receive quiz answers, and return the Install magic link.

The **Plan and sign-up** Flow ending captures the visitor's email after the quiz and results. FloKit sends a signed `signup_requested` request to your receiver with the email and completed questionnaire. Your receiver returns an onboarding magic link, which FloKit uses on the **Install** button. No payment, subscription, price, currency, or Package fields are sent.

The customer journey is **quiz → separate results → View my plan → personalized plan and email sign-up → Install**. This ending is available for GamiFest. The results page stays separate from the plan and sign-up page.

## Configure the dashboard

1. Select **GamiFest** in the dashboard's App selector.
2. Open **Initiatives → Create Initiative → Flow and offers**.
3. Set **Flow ending → Plan and sign-up**. The other choices include **Paywall** and **Direct install**.
4. Under **Review and launch**, choose **Generate without traffic** while checking the integration. Ads remain paused; normal generation costs still apply. Choose **Save draft without generating** to save configuration without starting generation.
5. After generation completes, select the generated Flow and choose **Open live Flow** to check the customer journey. Preview does not submit a real sign-up.

[Open the GamiFest initiative form](https://dashboard.flokitai.com/initiatives?create=initiative\&appId=app_gamifest\&flowEnding=signup_install). The configured value is `signup_install`. Existing published Flows retain their previous ending; create a new Plan and sign-up Flow to use this journey.

## Configure the receiver

Your FloKit contact configures a separate active **production** endpoint for the GamiFest App and the `signup_requested` event. Use the existing GamiFest HTTPS receiver at `https://api.gamifest.ai/webhooks/flokit`, or agree another public HTTPS address with your FloKit contact. Keep the `subscription_started` handler for paid journeys.

The endpoint's response contract is `optional_app_handoff_v1`, with `signupOnboardingOnly: true`. The generic **Add endpoint** form configures subscription events; ask your FloKit contact to provision the sign-up endpoint. Inspect the configured receiver in **Webhooks → Endpoints**, and delivery attempts in **Webhooks → Deliveries**. Use **Webhooks → Signing secret** to install the Company's existing signing secret in your receiver's secret manager. Owners and admins can reveal the secret; viewers cannot.

Generic **Send test** does not exercise sign-up and returns `SIGNUP_TEST_REQUIRES_FLOW` for this endpoint. Use a published Plan and sign-up Flow to test the complete journey.

## Signed request

Verify the signature over the original request bytes before parsing JSON, using the [existing signature verifier](https://docs.flokitai.com/webhooks/signatures.md). Sign-up uses the same Company signing secret, header format, timestamp tolerance, and rotation overlap as subscription webhooks. Never put the signing secret in browser code, URLs, logs, or chat.

```text theme={null}
Content-Type: application/json
FloKit-Signature: t=<unix_milliseconds>,v1=<lowercase_hex_hmac>
FloKit-Event-Id: <event_id>
FloKit-Delivery-Id: <delivery_id>
FloKit-Attempt: <scheduled_attempt>
Idempotency-Key: <event_id>
```

Store or process the request durably and deduplicate business effects by the signed body's `event_id`. Automatic retries retain the same event ID and body, with fresh signatures. Do not deduplicate by email or delivery ID.

## Request payload

This example uses fictional identifiers and email. Real requests contain all completed, answered questions on the visitor's quiz path.

```json theme={null}
{
  "event_id": "wh_evt_signup_example_001",
  "event_type": "signup_requested",
  "created_at": "2026-10-13T07:00:00.000Z",
  "environment": "production",
  "customer": {
    "id": "anonymous_example_001",
    "id_type": "anonymous_id",
    "email": "example@example.com"
  },
  "webflow": {
    "flow_id": "flow_example_signup_001",
    "questionnaire": {
      "questionnaire_id": "questionnaire_example_signup_001",
      "questions_and_answers": [
        {
          "question_id": "s_goal",
          "question": "What would you like to improve?",
          "question_type": "single_select_text",
          "answer": [{ "id": "goal_energy", "text": "Have more energy" }]
        },
        {
          "question_id": "s_minutes",
          "question": "How many minutes can you spend on a break?",
          "question_type": "numeric_input",
          "answer": [{ "text": "5", "unit": "minutes" }]
        }
      ]
    }
  }
}
```

| Field | Meaning |
| - | - |
| `event_id` | Stable event identity and deduplication key. |
| `event_type` | Always `signup_requested`. |
| `created_at` | Event creation time in UTC. |
| `environment` | Endpoint environment, `production` or `sandbox`. |
| `customer.id` | Anonymous Flow-session identity. This is not a verified existing app account. |
| `customer.id_type` | Always `anonymous_id`. |
| `customer.email` | Email submitted on the final plan/sign-up page, normalized to lowercase. |
| `webflow.flow_id` | Flow associated with the sign-up. |
| `webflow.questionnaire.questionnaire_id` | Published questionnaire identity. |
| `webflow.questionnaire.questions_and_answers` | Validated final questions and answers, including published question text and type. |
| `questions_and_answers[].answer` | Array of answers, each containing `text`, with optional `id` and `unit`. |
| `webflow.questionnaire.unit_preferences` | Optional map of the visitor's selected units. |

The request has no `purchase`, `provider`, `package`, billing, price, or currency fields. Do not require an empty payment object. Treat email and questionnaire answers as sensitive customer data; restrict access and retention, and do not log the full payload.

## Return the Install magic link

Return **HTTP 200** with **Content-Type: application/json** and this body. Replace the example link with your complete GamiFest onboarding destination.

```json theme={null}
{
  "version": 1,
  "event_id": "wh_evt_signup_example_001",
  "customer_id": "anonymous_example_001",
  "handoff": {
    "deeplink": "https://example.onelink.me/ABCD?code=EXAMPLE_ONLY",
    "issued_at": "2026-10-13T07:00:01.000Z",
    "expires_at": "2026-10-13T07:20:01.000Z"
  }
}
```

* `version` is `1`. Copy `event_id` exactly from the request and `customer_id` exactly from `customer.id`.
* `deeplink` is the complete partner-generated onboarding link. FloKit places the validated link on **Install**; no separate callback is required.
* Use UTC timestamps for `issued_at` and `expires_at`. Expiry must be in the future, later than issuance, and no more than **30 minutes** after issuance. Issuance allows at most one minute of future clock skew.
* Return uncompressed JSON within the **10-second** request timeout. The response body limit is **4096 bytes**.
* A duplicate event must not create another account or invalidate a previously returned unexpired link. Return a valid handoff for the same event and customer.

An email submission does not prove email ownership. For an email already registered, require email verification or the normal app login before granting existing-account access. A sign-up onboarding link must not sign an unverified visitor into an existing account.

**Plain OK, HTTP 204, a missing handoff, or an invalid/expired link does not enable Install.** A 2xx acknowledgment with a missing or invalid handoff does not automatically retry the webhook. For a temporary receiver failure, return a retryable error instead of acknowledging an unusable handoff. Network failures, HTTP 408/425/429, and 5xx follow the [existing retry policy](https://docs.flokitai.com/webhooks/delivery-retries-and-troubleshooting.md).

## Meta StartTrial

For GamiFest, a successful sign-up represents **StartTrial**. After your receiver returns a valid handoff, FloKit submits the server Meta event with the exact plan/sign-up page URL as its source, including `view=install`. Existing consent and matching requirements apply.

The same publication and Flow session use one stable conversion identity across retries. Form views, failed sign-ups, pending webhooks, and Install clicks do not emit StartTrial. This milestone does not assert payment, revenue, or a billing subscription.

## Integration checklist

1. Confirm your receiver verifies signatures, accepts `signup_requested` without payment fields, and deduplicates by `event_id`.
2. Confirm the JSON response identities, link lifetime, duplicate handling, and existing-account email verification behavior.
3. Confirm your receiver deployment is complete, then use a newly generated Plan and sign-up Flow for a real sign-up.
4. Check successful delivery in **Webhooks → Deliveries**, the returned destination on **Install**, and Meta's accepted **StartTrial** receipt. A queued event or webhook acknowledgment alone does not confirm Meta acceptance.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.