RecomlyRecomlyRecomlyDocs
Recomly APIEndpoints

Upload logo URL

Obtain a pre-signed S3 URL to upload an organization logo directly from the browser or client.

POST /api/app/branding/logo

Returns a short-lived pre-signed S3 PUT URL and the public CDN URL the logo will be accessible at once uploaded. The actual file upload goes directly from your client to S3 — it does not pass through the Recomly API.

After uploading the file to S3, call Update branding with the returned logoUrl and logoKey to persist the logo against your organization.

Requires the customBranding feature entitlement.


Request

See API Basics for required headers.

Body

FieldTypeRequiredDescription
contentType"image/png" | "image/jpeg" | "image/gif"YesMIME type of the logo file you will upload.

Upload flow

This endpoint is step one of a three-step flow:

  1. Call this endpoint with the contentType of your file.
  2. PUT the file to uploadUrl directly from your client. Include Content-Type: <contentType> as a header. No auth header — the URL is self-authenticating.
  3. Call Update branding with logoUrl and logoKey from the response to save the logo against your organization.

If your organization already has a saved logo, calling this endpoint automatically removes the old S3 object. You must still complete step 3 — until then, the old logoUrl remains in your branding record.

The pre-signed URL expires after 5 minutes. Complete the S3 PUT upload before then. If the URL has expired, call this endpoint again to get a fresh one.


Sample request

curl -X POST https://api.recomly.com/api/app/branding/logo \
  -H "Authorization: Bearer rk_live_abc123:def456" \
  -H "Content-Type: application/json" \
  -d '{ "contentType": "image/png" }'

Sample response

Status: 200 OK

{
  "uploadUrl": "https://recomly-uploads-prod.s3.amazonaws.com/logos/a1b2c3d4-0000-4000-8000-e5f6a7b8c9d0/1744051800000-550e8400-e29b-41d4-a716-446655440000.png?X-Amz-Algorithm=...&X-Amz-Expires=300&...",
  "publicUrl": "https://app.recomly.com/logos/a1b2c3d4-0000-4000-8000-e5f6a7b8c9d0/1744051800000-550e8400-e29b-41d4-a716-446655440000.png",
  "key": "logos/a1b2c3d4-0000-4000-8000-e5f6a7b8c9d0/1744051800000-550e8400-e29b-41d4-a716-446655440000.png"
}

Response fields

FieldTypeDescription
uploadUrlstringPre-signed S3 PUT URL. PUT your logo file to this URL. Expires in 5 minutes.
publicUrlstringThe CDN URL the logo will be accessible at once uploaded. Pass this to the Update branding endpoint as logoUrl.
keystringInternal S3 object key. Pass this to the Update branding endpoint as logoKey.

Uploading the file to S3

# Step 2 — PUT the file directly to the pre-signed URL (no auth header)
curl -X PUT "<uploadUrl>" \
  -H "Content-Type: image/png" \
  --data-binary @logo.png

A successful upload returns HTTP 200 with an empty body. Any non-200 response means the upload failed — check that the URL has not expired and that the Content-Type header matches the value you passed in step 1.


Error responses

See API Basics for standard status codes and error response format.

StatusWhen
400 Bad RequestcontentType is missing or not one of the allowed MIME types.
403 ForbiddenCaller does not have the admin role, or the customBranding feature is not enabled for this organization.

On this page

We use cookies

We use essential cookies to keep the site working, and optional analytics cookies to understand how it's used. Read our Privacy Policy.