This guide shows employers how to deliver identity, organization, language, and visual-style settings to ZelSafe using Apple Managed App Configuration. ZelSafe still runs offline-first: learning progress, quiz results, audio completion, audit logs, and certificates remain local to the device unless the learner exports them.
Pre-fill the employee name, email, and organization so greetings, certificates, and local audit exports use the right company context.
Set a default language and limit which installed or downloadable language packs employees are allowed to see.
Set a tenant-specific default visual style and restrict the Visual Style screen to approved styles.
Store support phone, email, URL, HR destination email, tenant ID, and campaign code values for local enterprise context and exports.
Important: MDM does not install content packs. If a language or visual style is allowed but not bundled in the app, the matching pack must already be available through the ZelSafe CDN for the user to download. Customer logo, display text, and action links come from the selected visual-style pack, not directly from MDM.
Add these keys to the MDM provider's managed app configuration for the ZelSafe iOS app. Most MDM systems provide either a key/value form or an XML property-list editor.
{
"EmployeeName": "Haja Mo",
"EmployeeEmail": "[email protected]",
"organization_name": "Citibank",
"tenant_id": "citibank-us",
"default_language": "en",
"allowed_languages": ["en", "fr", "de"],
"default_visual_style": "vs-citibank",
"allowed_visual_styles": ["vs-citibank"],
"support_phone": "+18005550100",
"support_email": "[email protected]",
"support_url": "https://security.citibank.example",
"HREmail": "[email protected]",
"zelsafe_private_dashboard": "https://rocheston.com/zpd",
"zelsafe_private_dashboard_pin": "1234",
"CampaignCode": "rccs-2026-q3"
}
Use these samples as starting points. Replace the company, tenant, support, and campaign values before deployment.
Locked tenant deployment. Best for a company that wants employees to see only its branded visual style and approved languages.
{
"EmployeeName": "First Last",
"EmployeeEmail": "[email protected]",
"organization_name": "Citibank",
"tenant_id": "citibank-us",
"default_language": "en",
"allowed_languages": ["en", "fr", "de"],
"default_visual_style": "vs-citibank",
"allowed_visual_styles": ["vs-citibank"],
"support_phone": "+18005550100",
"support_email": "[email protected]",
"support_url": "https://security.citibank.example",
"HREmail": "[email protected]",
"zelsafe_private_dashboard": "https://rocheston.com/zpd",
"zelsafe_private_dashboard_pin": "1234",
"CampaignCode": "citibank-rccs-2026-q3"
}Language restriction only. Best when the employer does not need a custom visual style but wants to control which languages appear.
{
"organization_name": "Acme Corporation",
"tenant_id": "acme-global",
"default_language": "en",
"allowed_languages": ["en", "fr", "de"],
"CampaignCode": "acme-awareness-2026"
}Custom visual style only. Best when the app should remain English but use a company-specific visual style and branding pack.
{
"organization_name": "Citibank",
"tenant_id": "citibank-us",
"default_language": "en",
"allowed_languages": ["en"],
"default_visual_style": "vs-citibank",
"allowed_visual_styles": ["vs-citibank"]
}Pilot group. Best for a small pilot where the employer wants employee identity and campaign tracking but no restrictions.
{
"EmployeeName": "First Last",
"EmployeeEmail": "[email protected]",
"organization_name": "Pilot Company",
"tenant_id": "pilot-company",
"zelsafe_private_dashboard": "https://rocheston.com/zpd",
"zelsafe_private_dashboard_pin": "1234",
"CampaignCode": "pilot-2026"
}| Key | Type | Required | What ZelSafe Does |
|---|---|---|---|
EmployeeName | String | Recommended | Pre-fills the employee name. Used in app personalization, certificates, and local audit exports. |
EmployeeEmail | String | Optional | Pre-fills the employee email. Also accepts LearnerEmail or Email. |
organization_name | String | Recommended | Pre-fills the organization/company field. Also accepts OrgName, OrganizationName, Organization, CompanyName, or Company. |
tenant_id | String | Recommended | Stores a stable tenant identifier such as citibank-us. Also accepts TenantID or TenantId. |
default_language | String | Optional | Selects the default language at launch and writes it to the selected language setting. Also accepts DefaultLanguage. |
allowed_languages | Array of strings, or comma-separated string | Optional | Only listed languages appear in the Language screen. Also accepts AllowedLanguages. |
default_visual_style | String | Recommended for branded deployments | Selects the tenant style and writes it to the selected visual style setting. Also accepts DefaultVisualStyle and normalizes citibank to vs-citibank. |
allowed_visual_styles | Array of strings, or comma-separated string | Recommended for branded deployments | Only listed visual styles appear in the Visual Style screen. Also accepts AllowedVisualStyles and normalizes values to vs-.... |
support_phone | String | Optional | Stores enterprise support phone metadata. Also accepts SupportPhone. |
support_email | String | Optional | Stores enterprise support email metadata. Also accepts SupportEmail. |
support_url | String | Optional | Stores enterprise support website metadata. Also accepts SupportURL or SupportUrl. |
HREmail | String | Optional | Pre-fills a destination email used when the learner exports or shares employer-facing training records. |
zelsafe_private_dashboard | HTTPS URL string | Optional | Enables a learner-controlled upload button on the RCCS certificate sharing screen. Also accepts ZelSafePrivateDashboard, PrivateDashboardURL, or PrivateDashboardUrl. The URL must use https://. |
zelsafe_private_dashboard_pin | 4-digit string | Optional | Provides the organization PIN for the private dashboard upload endpoint. Also accepts ZelSafePrivateDashboardPIN, PrivateDashboardPIN, or PrivateDashboardPin. The app sends this value as multipart field zpd_pin beside the audit JSON file. |
CampaignCode | String | Optional | Stores the employer campaign or rollout code for local export context. Also accepts CampaignID or CampaignId. |
Some MDM tools ask for XML plist instead of JSON. The values below are equivalent to the recommended payload.
<dict> <key>EmployeeName</key> <string>Haja Mo</string> <key>EmployeeEmail</key> <string>[email protected]</string> <key>organization_name</key> <string>Citibank</string> <key>tenant_id</key> <string>citibank-us</string> <key>default_language</key> <string>en</string> <key>allowed_languages</key> <array> <string>en</string> <string>fr</string> <string>de</string> </array> <key>default_visual_style</key> <string>vs-citibank</string> <key>allowed_visual_styles</key> <array> <string>vs-citibank</string> </array> <key>support_phone</key> <string>+18005550100</string> <key>support_email</key> <string>[email protected]</string> <key>support_url</key> <string>https://security.citibank.example</string> <key>HREmail</key> <string>[email protected]</string> <key>zelsafe_private_dashboard</key> <string>https://rocheston.com/zpd</string> <key>zelsafe_private_dashboard_pin</key> <string>1234</string> <key>CampaignCode</key> <string>rccs-2026-q3</string> </dict>
The MDM profile points the employee to a visual style, such as vs-citibank. The actual logo, branding text, and clickable support links live inside that visual-style pack. ZelSafe reads the pack from the selected visual-style language-pack folder. If a visual-style card image is missing, the app falls back to the regular bundled English card image.
default_visual_style: vs-citibanklanguage_packs/vs-citibank/ from the ZelSafe CDNlanguage_packs/vs-citibank/
zelcards/
01-scams-and-phishing/
content/
Matching English Card Filename.jpg
today/
Optional Today overrides
branding/
logo.png
branding.json{
"logo": "logo.png",
"top_text": "Citibank Security Awareness",
"bottom_text": "If you suspect fraud, call Security Hotline: +1-800-555-0100",
"links": [
{ "label": "Call Security", "type": "phone", "value": "+18005550100" },
{ "label": "Report Online", "type": "url", "value": "https://security.citibank.example" },
{ "label": "Email Security","type": "email", "value": "[email protected]" }
]
}branding/logo.png, ZelSafe displays just the logo.logo.jpg, logo.jpeg, or logo.webp when branding.json does not name a logo.top_text can also be supplied as branding/top.txt.bottom_text can also be supplied as branding/bottom.txt or branding/text.txt.phone, url, or email.phone links, ZelSafe keeps only digits and + before opening the phone URL.url links, include https:// or provide a host; ZelSafe adds https:// if no scheme is present.email links, provide a normal email address. ZelSafe opens a mail URL.MDM values are plain strings, arrays, or comma-separated strings. Do not put Markdown in MDM keys. The formatting below applies to ZelSafe content files such as sample-scam/scenario text inside language packs.
| Format | Supported | Example |
|---|---|---|
| Bold inline text | Yes | Never share **verification codes** with anyone. |
| Underlined/link-style inline text | Yes | Visit <u>https://example.test</u> only in training examples. |
| Recognized headings | Yes | WHAT IT IS, SAMPLE SCAM, SAMPLE SCENARIO, SAMPLE (...), EXAMPLE |
| Blank lines | Yes | Use blank lines to separate readable blocks of scenario text. |
| General Markdown | No | Lists, tables, images, headings with #, and Markdown links are not parsed by the app renderer. |
SAMPLE SCAM TEXT Bank Verification Alert "Your account is locked. Confirm your identity at <u>secure-bank-login.example</u>." WHAT IT IS This is a credential phishing attempt. The attacker uses urgency and a fake website to steal **login details**.
If the MDM profile includes zelsafe_private_dashboard with a valid HTTPS URL and zelsafe_private_dashboard_pin with a 4-digit PIN, ZelSafe shows Upload Results to ZelSafe Private Dashboard on the RCCS certificate sharing screen. The learner must press the button and confirm the upload. ZelSafe does not upload automatically.
zpd_pin field + file = audit JSON only{"accepted": true} — reference id & message shown to the learner| Item | Behavior |
|---|---|
| Endpoint | The value of zelsafe_private_dashboard. It must be a valid https:// URL with a host. |
| HTTP method | POST |
| Body format | multipart/form-data |
| PIN field | zpd_pin, copied from the MDM value zelsafe_private_dashboard_pin. The dashboard should reject incorrect PINs with HTTP 403. |
| File field | file |
| File content type | application/json |
| Uploaded data | Only the locally generated audit JSON file from the employer/RCCS certificate package. The PDF certificate, screenshots, app database, and media files are not uploaded. |
| Timeout | 30 seconds. |
| Success | A 2xx HTTP response with JSON containing "accepted": true. Optional submitted_at, reference_id, and message values are displayed or stored by ZelSafe. |
POST /zpd HTTP/1.1
Host: rocheston.com
Content-Type: multipart/form-data; boundary=ZelSafeBoundary...
Accept: application/json
--ZelSafeBoundary...
Content-Disposition: form-data; name="zpd_pin"
1234
--ZelSafeBoundary...
Content-Disposition: form-data; name="file";
filename="ZelSafe-Audit-Log.json"
Content-Type: application/json
{ "certificate": { ... }, "auditLog": [ ... ] }
--ZelSafeBoundary...--{
"accepted": true,
"submitted_at": "2026-07-28T10:45:00Z",
"reference_id": "ZPD-20260728-001",
"message": "Audit JSON accepted."
}No automatic retries: ZelSafe does not retry in the background. The learner can press upload again after fixing the connection or after the dashboard service is restored.
2xx response, ZelSafe shows the HTTP status and any readable server message.2xx but does not return JSON with "accepted": true, ZelSafe treats the upload as rejected.default_visual_style to the tenant style, for example vs-citibank.allowed_visual_styles to only the approved tenant styles.allowed_languages to only languages approved for that rollout.zelsafe_private_dashboard to the employer's HTTPS upload endpoint and zelsafe_private_dashboard_pin to the 4-digit PIN expected by that endpoint.Expected result: the employee sees only the allowed languages and visual styles. The default language and tenant style are selected automatically when the profile is present.
zelsafe_private_dashboard and zelsafe_private_dashboard_pin are configured, the RCCS certificate sharing screen shows the upload button and asks before uploading the audit JSON file.Push the managed configuration, publish your style pack, and every managed device opens ZelSafe in your company's context.