We welcome all developers to use our API and source code to create applications on our platform. There are several things we require from all developers for the moment.
This fork requires iOS 18 or later. Choose identity opens the native Identity Manager,
also available in Settings. Connect to your home DC domain before creating an identity.
The app embeds no DC list; it discovers each account's home from the domain you enter.
The DC publishes its signed profile at /.well-known/blah/profile.cbor and advertises a
plain TCP MTProto endpoint. iOS 18–25 supports Ed25519/P-256 DC profile signatures;
ML-DSA requires iOS 26. Its identity, database generation and signed version are
pinned per account; another home or identity requires another account slot. Unbound
legacy transport sessions require a fresh account.
On launch, the main app refreshes the home profile. If the domain is unreachable, it keeps
the saved home only if it still verifies; any returned profile that fails verification or
is older is rejected. Extensions reuse the saved verified home without contacting the profile domain.
Create a name on a Diem profile host, use a domain you host yourself, or import a
password-encrypted identity file. Shared BlahDiem CBOR/HPKE files containing identity
recovery authority are accepted; device-only files and JSON backups are unsupported.
Hosted identities publish automatically after changes and signup; failed publication
retains the signed revision and can be retried in Identity Manager. For your own domains,
publish the exported public profile.cbor at every listed HTTPS domain with content type
application/cbor, including the updated account number after signup, then sign in again.
Sign-in first uses the identity domain. Admission email appears only when the DC asks for
it; signup without email goes straight to the name form. Existing email-code and two-step
password screens complete the DC's additional factors. Identity Manager also manages
domains, devices, profile validity and renewal; publish every authority change.
Identity custody lives in Keychain independently of chat storage. Native BlahDiem uses Secure Enclave P-256 device keys and seals the Ed25519 recovery key to another Secure Enclave key. Unlock with Face ID or Touch ID is optional; there is no separate identity passcode. Encrypted file export/import requires a nonempty backup password with no additional length or complexity rules. Sync recovery with iCloud Keychain is opt-in and synchronizes the recoverable identity key and profile, not the hardware device keys. Recovery fetches the latest hosted profile, enrolls a fresh Secure Enclave device, and requires publication. Native recovery exports are for native recovery; they do not export the hardware device key as a browser identity. Custody locks when leaving management, on backgrounding, or after 15 idle minutes; continuing sign-in retains it subject to the same idle and background locks. Automatic renewal runs only while unlocked. Creation and recovery require real Secure Enclave hardware; the simulator has no software-key fallback.
Every profile domain is a username candidate. Publish the profile at each domain, then verify it with the home DC and choose active usernames in Edit Profile.
The integration is isolated in BlahIdentity,
BlahIdentityUI, and the
network adapter.
BlahDiem and its native Diem crypto backend are
upstream Swift package dependencies. Their revisions live in
Package.swift; the committed
Package.resolved locks the transitive graph.
MODULE.bazel imports the package products through
rules_swift_package_manager for both app builds and generated Xcode projects.
The current integration requires Swift 6.4; Xcode and Bazel versions are pinned in
versions.json. Signed-home connections use MTProtoKit until the alternative engine
supports the same device-proof binding and signed endpoint/RSA pin contract. Saved
authorizations are checked against the identity, device and cache namespace before reconnecting.
To update a revision, edit the manifest, then regenerate both lockfiles:
swift package --package-path build-system/SwiftPackages resolve
build-input/bazel-9.2.0-darwin-arm64 mod depsRecovery exports use BlahDiem’s KeyFile API and the platform PBKDF2 adapter; hardware
keys remain non-exportable.
The package integration tests
exercise profile encoding and sealed-key recovery against the fetched packages:
swift test --package-path build-system/SwiftPackages
# Or through Bazel on macOS:
build-input/bazel-9.2.0-darwin-arm64 test //build-system/SwiftPackages:BlahDiemPackageTests \
--apple_platform_type=macos --macos_minimum_os=15.0The Apple backend uses the upstream Swift Crypto package, which delegates to CryptoKit
on Apple platforms. No WASM is linked into the native app. Build through the repository's
build-system/Make/Make.py workflow
with the configured Xcode and signing environment. Device validation must cover cancelled
biometric prompts, lock/background transitions, publication after signup, file recovery,
and iCloud recovery on a second device.
- Obtain your own api_id for your application.
- Please do not use the name Telegram for your app — or make sure your users understand that it is unofficial.
- Kindly do not use our standard logo (white paper plane in a blue circle) as your app's logo.
- Please study our security guidelines and take good care of your users' data and privacy.
- Please remember to publish your code too in order to comply with the licences.
git clone --recursive -j8 https://github.com/TelegramMessenger/Telegram-iOS.git
Install Xcode (directly from https://developer.apple.com/download/applications or using the App Store).
- Generate a random identifier:
openssl rand -hex 8
- Create a new Xcode project. Use
Telegramas the Product Name. Useorg.{identifier from step 1}as the Organization Identifier. - Open
Keychain Accessand navigate toCertificates. LocateApple Development: your@email.address (XXXXXXXXXX)and double tap the certificate. UnderDetails, locateOrganizational Unit. This is the Team ID. - Edit
build-system/template_minimal_development_configuration.json. Use data from the previous steps.
python3 build-system/Make/Make.py \
--cacheDir="$HOME/telegram-bazel-cache" \
generateProject \
--configurationPath=build-system/template_minimal_development_configuration.json \
--xcodeManagedCodesigning
- Copy and edit
build-system/appstore-configuration.json. - Copy
build-system/fake-codesigning. Create and download provisioning profiles, using theprofilesfolder as a reference for the entitlements. - Generate an Xcode project:
python3 build-system/Make/Make.py \
--cacheDir="$HOME/telegram-bazel-cache" \
generateProject \
--configurationPath=configuration_from_step_1.json \
--codesigningInformationPath=directory_from_step_2
- Repeat the steps from the previous section. Use distribution provisioning profiles.
- Run:
python3 build-system/Make/Make.py \
--cacheDir="$HOME/telegram-bazel-cache" \
build \
--configurationPath=...see previous section... \
--codesigningInformationPath=...see previous section... \
--buildNumber=100001 \
--configuration=release_arm64
The app, extensions, and embedded iOS frameworks share the deployment target in
Telegram/BUILD. Keep their generated MinimumOSVersion values aligned
with the compiled binaries.
Occasionally, you might observe the following message in your build log:
"/Users/xxx/Library/Developer/Xcode/DerivedData/Telegram-xxx/Build/Intermediates.noindex/XCBuildData/xxx.xcbuilddata/build-request.json" not updated yet, waiting...
Should this occur, simply cancel the ongoing build and initiate a new one.
Following a system restart, the auto-generated Xcode project might encounter a build failure accompanied by this error:
ERROR: Skipping '@rules_xcodeproj_generated//generator/Telegram/Telegram_xcodeproj:Telegram_xcodeproj': no such package '@rules_xcodeproj_generated//generator/Telegram/Telegram_xcodeproj': BUILD file not found in directory 'generator/Telegram/Telegram_xcodeproj' of external repository @rules_xcodeproj_generated. Add a BUILD file to a directory to mark it as a package.
If you encounter this issue, re-run the project generation steps in the README.
Add --disableProvisioningProfiles:
python3 build-system/Make/Make.py \
--cacheDir="$HOME/telegram-bazel-cache" \
generateProject \
--configurationPath=path-to-configuration.json \
--codesigningInformationPath=path-to-provisioning-data \
--disableProvisioningProfiles
Each release is built using a specific Xcode version (see versions.json). The helper script checks the versions of the installed software and reports an error if they don't match the ones specified in versions.json. It is possible to bypass these checks:
python3 build-system/Make/Make.py --overrideXcodeVersion build ... # Don't check the version of Xcode