Skip to main content
A reward is optional and the SDK unlocks it after a participant finishes every step in the study and the recording has uploaded successfully to Candid. This sequencing is intentional: the reward is only granted once you have a confirmed upload, so you never hand out rewards for incomplete or failed sessions. You define what the reward is and how to fulfill it, Candid handles the timing and the fulfillment UI. Configure a reward by creating a Candid.Reward value and passing it to Candid.Configuration(reward:).

Reward properties

String
required
The text shown on the reward callout, inviting the participant to complete the test to get their reward. Write something specific so participants know what they are getting, e.g. "Complete the test to unlock your free 7-day trial.".
String
default:"gift.fill"
The SF Symbol name displayed as the reward icon on the callout. Defaults to "gift.fill". Use any symbol from the SF Symbols library that matches the nature of your reward.
@MainActor @Sendable () async throws -> RewardSuccessMessage
required
An async closure called on the main actor once the participant completed every step and the recording uploaded. Fulfill the reward here (e.g. call your backend), then return a RewardSuccessMessage value to tell the SDK how to proceed.

Success outcomes

After your successCompletion closure fulfills the reward, return a RewardSuccessMessage value to tell Candid what to display next.
RewardSuccessMessage
Candid displays its built-in thank-you screen. When you supply a message, it is shown as the subtitle; return .default() to use Candid’s default thank-you copy. Use this when you want a consistent, low-effort end screen without any extra work in your app.
RewardSuccessMessage
Candid dismisses its UI and hands control back to your app. Use this when you want to present your own confirmation screen, navigate to a specific part of your app, or trigger an in-app purchase flow.

Complete example

The example below unlocks a premium subscription trial after the participant completes the test. The successCompletion closure calls your backend, activates the trial, and returns .default so Candid shows a confirmation message.
If activating the reward requires a network call, perform it inside your successCompletion closure before returning. The Candid screen stays visible until the closure returns, so participants always see a response, never a blank screen.
Do not call Candid.register(trigger:) from inside the successCompletion closure. Starting a new study while the reward screen is still presented leads to undefined navigation behavior.