Pulse Phone docs
Photos and videos
6. Photos and videos
The camera needs screenshot-basic running before the phone.
Out of the box, photos are saved in the phone's media/ folder and served by your server. Photo
links must be https. With no phone_media_origin set, the phone uses your server's own
https://<name>.users.cfx.re address automatically, which is right for almost everyone. If you
set it yourself (for a domain of your own), use setr, not set, and start it with https://:
setr phone_media_origin "https://your.domain"Built-in media storage
The built-in provider needs no upload-service token. Photo, video and audio files live in
phone/media/; the database holds gallery metadata and links, not the large binary files.
Back up both together, and preserve media/ when updating the resource. Use a public HTTPS origin
for your server; localhost and a private PC address are not customer media URLs.
FiveManage
Pulse supports FiveManage for photo, video and audio uploads. Create a media API token with upload permissions, then open config/apiKeys.lua and set:
local MediaProvider = 'fivemanage'
local FiveManageToken = 'your-upload-token'This file is loaded on the server only. Never paste the token into config/config.lua or
config/apps.lua, which are shared with players. Preserve apiKeys.lua when upgrading.
Already using private server configuration? Keep your existing setup. These settings take
priority over apiKeys.lua; use ordinary set, never setr. Load them before ensure phone:
set phone_media_provider "fivemanage"
set phone_fivemanage_token "<your-upload-token>"Restart Pulse, run phone:health, then take a photo and open it in Photos. Upload requests and the
token remain server-side. The gallery receives the provider's HTTPS link. Authentication failures,
rate limits and upload errors produce an actionable administrator response without publishing keys.
A configured token is checked by the provider during uploads; startup checks its configuration.
S3, Cloudflare R2 and custom storage
Use an upload endpoint or an existing RegisterMediaProvider adapter for your object store.
S3/R2 require that adapter or endpoint; entering a bucket name or access key alone is not enough.
The adapter handles signing/uploading server-side and returns a permanent HTTPS delivery URL.
Do not return temporary browser blob: links or short-lived download links as gallery URLs.
set phone_media_provider "custom"
set phone_media_endpoint "https://<your-upload-host>/upload"
set phone_media_field "file"
set phone_media_auth_header "Authorization"
set phone_media_auth_value "Bearer <your-upload-token>"The endpoint receives multipart POST data and returns JSON with a url field. A registered
adapter selects its own name with phone_media_provider; see Exports for
RegisterMediaProvider. Use explicit provider selection: Pulse never guesses credentials or
silently changes storage providers after an upload error. Restart Pulse after changing settings.
Discord webhook storage is retained for existing installations. Its expiring attachment links are unsuitable for a permanent gallery; use the built-in provider or durable object storage.
Media troubleshooting
| Symptom | Reason and fix |
|---|---|
| Upload service rejects the request | Check the private token and its photo/video/audio upload permissions. A 401/403 means authorization; 429 means the service rate limit. Retry after the limit resets. |
| Capture stays busy then reports failure | The storage request timed out. Check service availability and outbound network access, then capture again. Failed uploads do not become gallery records. |
| Photo exists but the thumbnail does not load | Check the delivery URL is public HTTPS, the object still exists, and the provider's host is allowed. Refresh after correcting access. |
| Local media disappears after an update | Restore the media/ backup together with the database. Keep that folder when replacing the resource. |
| Video has no audio | Enable recording audio and grant FiveM microphone access. Check the microphone is available before recording. |
Gallery deletion removes the phone's record. Local uploads are reclaimed after the reference grace period when no supported phone record uses them. Remote object retention/deletion follows your storage service or custom adapter's policy; deleting a gallery tile is not a provider-wide purge.
Which links are kept. The server stores a photo, avatar, attachment or post link only if it
comes from the phone's own store, your provider's hosts, a host your provider returned, or
Config.Media.allow.hosts / .domains (config/apps.lua). Config.Media.allow.external = true
switches the check off. That is not recommended: it lets in gore and IP-logger links.
Upload limits. Each player may upload Config.Media.dailyMb megabytes a day (250 by default,
0 = no limit). The count starts again at a restart. Uploads are also limited to 12 a minute per
player: change that with Config.Security.rates.uploads = { n = 12, per = 60 }.