API proxy
How to route the Purchasely API traffic through a proxy when api.purchasely.io is unreachable, for example in mainland China
Context
The SDK sends its API requests to api.purchasely.io. Some networks block that host. In mainland China, the Great Firewall blocks it, while the paywall host and the tracking host stay reachable. The API proxy gives the SDK a different base URL for the API host.
Purchasely operates a proxy at https://svc.purchasely.io. You can also host your own proxy.
SDK v6.1.0+ requiredThe proxy is available from v6.1.0 on iOS and on Android. It is not available on React Native, Flutter or Cordova.
What the proxy moves
Only the API host moves. The proxy never moves paywall.purchasely.io and tracking.purchasely.io. On iOS, these two hosts follow environment(_:), which targets production by default.
iOS
// The Purchasely proxy
Purchasely
.apiKey("X-API-KEY")
.proxy()
.start()
// Your own proxy
Purchasely
.apiKey("X-API-KEY")
.proxy(api: URL(string: "https://proxy.example.com"))
.start()
// No proxy: the SDK goes back to api.purchasely.io
Purchasely
.apiKey("X-API-KEY")
.proxy(api: nil)
.start()The parameter is a URL?. The no-argument form proxy() selects the Purchasely proxy. The nil value restores api.purchasely.io. A chain that calls neither form keeps the current setting.
Android
// The Purchasely proxy, or your own
Purchasely.Builder(applicationContext)
.apiKey("X-API-KEY")
.proxy(api = "https://svc.purchasely.io")
.stores(listOf(GoogleStore()))
.build()
.start { error -> }
// No proxy: the SDK goes back to api.purchasely.io
Purchasely.Builder(applicationContext)
.apiKey("X-API-KEY")
.proxy(api = null)
.stores(listOf(GoogleStore()))
.build()
.start { error -> }The parameter is a String?. The null value restores api.purchasely.io, and it also clears a proxy that an earlier build() set. The Purchasely { } DSL provides the same method.
The no-argument form does the opposite on the two platformsOn iOS,
proxy()selects the Purchasely proxy. On Android,proxy()restoresapi.purchasely.io, because the parameter has a default value ofnull. Always write the URL. The explicit form gives the same result on both platforms.
| Call | iOS | Android |
|---|---|---|
proxy() | Selects https://svc.purchasely.io | Restores api.purchasely.io |
proxy(api:) with a URL | Selects that URL | Selects that URL |
proxy(api: nil) and proxy(api = null) | Restores api.purchasely.io | Restores api.purchasely.io |
URL rules
The SDK accepts a base URL that follows these rules:
- The scheme is
https. The SDK refuseshttp. - The URL carries a host.
- The URL carries no query and no fragment.
- The URL carries no credentials. Authenticate your own proxy with a header instead.
A path is valid. Both https://svc.purchasely.io and https://proxy.example.com/purchasely work. Write the URL with or without a trailing slash. Each SDK normalizes that character for its own network layer.
The SDK refuses any other value, writes an error log, and keeps the production host. The refusal never stops the initialization, so a wrong value never breaks the SDK.
The proxy belongs to the initialization
Both SDKs read the base URL when they build their network clients. They read it once. For this reason, the proxy is an option of the initialization chain, and neither platform provides a runtime setter.
Logs
The error log redacts the query, the fragment and the credentials of the refused URL, because the message must not carry a secret. The iOS SDK can also upload its logs to Purchasely for support. Read SDK diagnostics and observability for more information.
Updated about 1 hour ago

