Creator websites

Store a website asset

Hands back a one-time URL to upload a file to, and the permanent address it will be served at. Needs content: write, and is a write.

For the things a page links to rather than contains: images, video, audio, fonts, and shared stylesheets or scripts. Put their URLs in your HTML; nothing here changes a page.

The bytes go straight from you to storage and never pass through this API or through a model, so url answers 404 until you have sent them. Send them with a PUT carrying the Content-Type you named, before upload.expires_at.

content_type is what the upload is minted for, and storage enforces it on the PUT itself: a file of a different type is refused there rather than stored wrongly. image/svg+xml is not accepted, because an SVG navigated to directly runs its own script on the storage origin, which every creator's assets share.

Storage not being configured on this deployment answers 503 rather than accepting a file Commune cannot keep.

Publishes no event.

post/newsletters/{newsletter}/website-assets

Request

  • Base URL: https://api.usecommune.com
  • URL: https://api.usecommune.com/newsletters/{newsletter}/website-assets
  • Auth: one of:
    • HTTP bearer
    • OAuth 2 (authorization code, authorization URL https://usecommune.com/api/oauth/authorize, token URL https://usecommune.com/api/oauth/token, scopes: content:write)

Headers

Idempotency-Keystring required

A value of your choosing naming the change this request is making.

Send the same value again to retry the same request. Commune replays the answer the first attempt gave instead of making the change twice, and marks the replay with an Idempotent-Replay: true response header. Send a different value for a different change: a key reused for a request that differs in any way answers 409, because replaying an answer to a question you did not ask is a wrong answer you could not detect.

A UUID per change is the usual choice. Remembered for 24 hours, per credential, so two credentials choosing the same value never see each other's answers.

Required, not optional.

Request body

filenamestring required

What to call the file. Shown back to you and used to build the stored path, which also carries a random component so an upload cannot overwrite an earlier one.

content_typestring required

The file's type. Images, video, audio, fonts, stylesheets, scripts and JSON are accepted; image/svg+xml is not, because an SVG navigated to directly runs its own script on the storage origin every creator's assets share. An unaccepted type answers 400 and lists the ones that are.

Example request

{
  "content_type": "image/png"
}

Response

The asset, and where to send the file. byte_size and uploaded_at are null until the bytes arrive.

object'site_asset' required

Always site_asset.

idstring uuid required

Stable identifier.

filenamestring required

What you called the file. The stored path carries a random component so one upload can never overwrite another, which also makes the stored path useless to show, so this is what is shown instead.

content_typestring required

The type the upload was minted for. Storage enforces it on the upload itself, so a file of a different type is refused there rather than stored under the wrong type.

urlstring uri required

Where the file is served, permanently. Put this in your HTML. It answers 404 until the bytes have been uploaded.

byte_sizeinteger nullable required

How large the stored file is, or null until it arrives. Commune does not see the bytes, so this is what storage reported rather than what was promised.

uploaded_atstring date-time nullable required

When storage accepted the file, or null while it is still expected.

created_atstring date-time required

When the upload was minted.

Example response

{
  "newsletter": {
    "object": "newsletter",
    "id": "9a4c1c6e-0f2b-4f47-9d3f-6d1b1a2c3d4e"
  },
  "content_type": "image/png"
}

Changes

No recorded changes to this operation across all 1 revision of this API.