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://:

server.cfg
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:

Lua
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:

server.cfg
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.

server.cfg
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 }.