Guides
Modular signup flow
Configure your signup form in the Hub and render it from GET /v1/signup-config.
Your users sign up through a form that you compose from modules (phone number, email, tag name, first and last name, birth date, country, referral code, acceptance of terms). You configure it in the Hub, under Settings, then Signup, and your app reads the published result from the API. The SDK's UI components render directly from it.
How configuration works#
- You edit a draft, preview it, then publish it. Published versions are immutable and numbered 1, 2, 3, and you can roll back to an earlier one (it is republished under a new number).
- The phone module is always present, enabled and required: it is the user's identity and it is verified by a one-time code.
- Each enabled module needs a label in English and in your default language. Supported languages:
en,fr,es,de,it,pt.
Read the published flow#
Retrieve the published signup flow with any key of the project. Only enabled modules are returned, already ordered.
curl "https://sdk.tilt-pay.com/v1/signup-config" \
-H "Authorization: Bearer $TILT_PAY_API_KEY"{
"schema_version": 1,
"version": 3,
"default_locale": "en",
"modules": [
{
"id": "phone",
"input": "phone",
"verification": "code",
"required": true,
"order": 0,
"labels": { "en": { "label": "Phone number", "placeholder": "+33 6 12 34 56 78" } },
"options": {}
},
{
"id": "birth_date",
"input": "date",
"verification": null,
"required": true,
"order": 1,
"labels": { "en": { "label": "Date of birth" }, "fr": { "label": "Date de naissance" } },
"options": { "min_age": 18 }
}
]
}version is 0 while nothing has been published: the default flow (phone number and tag name) applies.
Collecting the values#
The flow tells your app which fields to ask. Once the user has filled the form, send the values to the API: the profile fields go in the body of Create a user or Update a user, validated against this same published flow (see User profiles and erasure), and the phone number is verified with the phone verification routes.
Rendering rules#
- Render modules in array order.
orderrepeats that position. - Pick the text for a module with this fallback chain: the user's locale, then
default_locale, thenen.enanddefault_localeare always present. inputtells you which control to show (phone,email,text,date,country,checkbox).verification: "code"means the value is verified by a one-time code.- Respect the module
options:min_agefor a birth date,allowed_countriesfor a country list,terms_urlandprivacy_urlfor the acceptance checkbox. - Ignore fields and modules you do not know: new modules can be added without a new API version.
Module reference#
| Module id | Input | Verification | Description | Options |
|---|---|---|---|---|
phone | phone | code | Phone number, verified by a one-time code. Always present, enabled and required. | — |
email | none | Email address. | — | |
tagname | text | none | Public tag name that other users can pay. | — |
first_name | text | none | First name. | — |
last_name | text | none | Last name. | — |
birth_date | date | none | Date of birth. | min_age (0 to 120) |
country | country | none | Country of residence. | allowed_countries (ISO 3166-1 alpha-2 codes) |
referral_code | text | none | Referral code. | — |
terms_acceptance | checkbox | none | Acceptance of your terms and privacy policy. | terms_url, privacy_url (https) |
JSON Schema#
The response is described by this JSON Schema, which you can use to validate it or to generate types.
Show the JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://tilt-pay.com/schemas/signup-config.json",
"title": "Tilt Pay public signup configuration (GET /v1/signup-config)",
"description": "Describes the modules of a project's published signup flow. SDK UI components are generated from `modules` (already ordered, only enabled modules).",
"type": "object",
"required": [
"schema_version",
"version",
"default_locale",
"modules"
],
"properties": {
"schema_version": {
"const": 1
},
"version": {
"type": "integer",
"minimum": 0,
"description": "0 = default configuration (nothing published yet)."
},
"default_locale": {
"enum": [
"en",
"fr",
"es",
"de",
"it",
"pt"
]
},
"modules": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"input",
"verification",
"required",
"order",
"labels",
"options"
],
"properties": {
"id": {
"enum": [
"phone",
"email",
"tagname",
"first_name",
"last_name",
"birth_date",
"country",
"referral_code",
"terms_acceptance"
]
},
"input": {
"enum": [
"phone",
"email",
"text",
"date",
"country",
"checkbox"
]
},
"verification": {
"enum": [
"code",
null
],
"description": "'code' = value verified by a one-time code (phone)."
},
"required": {
"type": "boolean"
},
"order": {
"type": "integer",
"minimum": 0
},
"labels": {
"type": "object",
"propertyNames": {
"enum": [
"en",
"fr",
"es",
"de",
"it",
"pt"
]
},
"additionalProperties": {
"type": "object",
"required": [
"label"
],
"properties": {
"label": {
"type": "string",
"maxLength": 80
},
"placeholder": {
"type": "string",
"maxLength": 80
},
"help_text": {
"type": "string",
"maxLength": 200
}
},
"additionalProperties": false
},
"description": "Always contains `en` and `default_locale`. Fall back to `default_locale`, then `en`."
},
"options": {
"type": "object",
"properties": {
"min_age": {
"type": "integer",
"minimum": 0,
"maximum": 120
},
"allowed_countries": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[A-Z]{2}$"
}
},
"terms_url": {
"type": "string",
"format": "uri"
},
"privacy_url": {
"type": "string",
"format": "uri"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"contains": {
"type": "object",
"properties": {
"id": {
"const": "phone"
},
"required": {
"const": true
}
},
"required": [
"id",
"required"
]
},
"minItems": 1
}
},
"additionalProperties": false
}