Jewelry AI · Saving and sharing

An image address here is signed on request, and it expires

Both directions the server signs come with an expiry attached: one hour to view a stored image, fifteen minutes to upload one. Nothing in those two paths hands you an address you can keep, so the decision a seller has to make is where the durable copy of the image is going to live.

There is no address you can file away

When the app shows you a stored image, the server signs an address for it and attaches a lifetime to that address. The address is not a name the image keeps. It is a permission to fetch the image, and the permission runs out.

The read path signs with an expiry of 3600 seconds — one hour (apps/api/src/storage/storage.service.ts, verified 2026-08-18). The write path, the address your device uploads a file to, is signed for 900 seconds — fifteen minutes — by the constant PRESIGN_PUT_EXPIRES_SEC in the same service. The gap is deliberate: reading lasts four times as long as uploading.

That is the whole mechanism behind the case this page exists for. An address that worked when it was copied and refuses when it is opened again has not lost the image; it has run out of permission.

One thing about a completed result is permanent, and it is not the address: every finished result carries a disclosure strip. That mechanism belongs to the page on the base photo standard and is not re-derived here.

The two windows, side by side

Both numbers are constants in the server's storage service (apps/api/src/storage/storage.service.ts, verified 2026-08-18).

DirectionLifetime of the signed addressWhat the number governsWhat it does not govern
Viewing a stored image1 hour (3600 seconds)How long that particular address can be used to fetch the imageHow long you can look at the image inside the app — the app may request another address
Uploading a file you chose15 minutes (900 seconds)How long that address accepts the upload; the same constant is the threshold the deletion logic uses to decide a late upload can no longer arriveHow long the transfer may take — a transfer that starts inside the window and finishes after it is not settled by the code

What the address is made of, and who chose it

Every part of the object's identity is decided on the server. Nothing about the name of the file comes from your device except the type it declared.

The server generates both the name and the location.
The key is built as a fixed prefix, a random UUID and an extension (apps/api/src/uploads/uploads.controller.ts, verified 2026-08-18). No bucket, folder or filename can be chosen from the app, so there is nothing for you to guess, remember or reconstruct later.
The prefix carries your user id, and the code keeps the key out of its logs.
Because the key contains an identifier, one sweeper deliberately avoids logging it (apps/api/src/storage/asset-purge-sweeper.ts:202, verified 2026-08-18). That is a logging decision in the code and this page does not present it as a privacy guarantee; nothing read here establishes who may use a signed address once it exists.
The extension is declared, not measured.
It is derived from the content type the client stated, not from the bytes of the file. An address that ends in one format is therefore not evidence that the stored object is that format.
The lifetime belongs to the address, not to the image.
A later call produces a newly signed address for the same stored object; in the model catalogue every call re-signs the list's image addresses (apps/jewelry-mobile/src/features/generation/create-flow/steps/model-source-step.tsx, verified 2026-08-18).

When an image is queued for deletion, new addresses stop

Deletion is not a single instant in this product: the image enters a queue first. From the moment it is in that queue, the server refuses to sign a new viewing address for it, and every read path goes through that same check on the asset's purge state (apps/api/src/storage/storage.service.ts, verified 2026-08-18). The refusal therefore arrives before the deletion itself has finished.

The gate governs new addresses, and only those. An address signed before the queue entry, still inside its hour, is not something this code answers for. So when you have to describe the situation to someone, describe the part that is established: the app will not produce a new address for that image.

In the model catalogue, every call signs the addresses again

The model catalogue keeps no client-side cache. Each change of filter fetches the list from the server again, and every call re-signs all of the image addresses; those signed addresses stop being valid after an hour, so there is no permanent image URL to collect from that screen (apps/jewelry-mobile/src/features/generation/create-flow/steps/model-source-step.tsx, verified 2026-08-18).

One consequence is worth saying plainly, because the opposite is easy to fear: fetched models are merged by id into the app's store, with the stated reason that a model you selected must still resolve at the review step after the filters have changed. Changing a filter does not lose the image of the model you already picked.

This behaviour has been read on the catalogue surface. It is not a statement about how every other screen in the app handles its addresses, and the one-hour lifetime is not a claim that images already drawn on your screen will break once the hour passes — that has not been verified.

Where the image is going decides what you need

The useful question is not how long the address lasts. It is whether an address is what the destination needs at all.

SituationChooseWhy
You want to look at the result now, or show it to someone while you both watch.The signed address is enough.It is valid for an hour from the moment it was signed, which covers looking at something.
A listing, a catalogue page or a storefront has to display the image from now on.The destination has to serve the image from an address of its own.Neither signed path described here produces an address that keeps working, so a destination pointed at one is pointed at something with an expiry on it.
You are keeping your own record of which image belongs to which piece.File the record against the piece, not against the address.The address expires and the object name is a server-generated UUID you never chose; neither is a handle you can build a filing system on.
You asked for an image to be deleted and now have to tell a customer where it stands.Say that the app will not issue a new address for it.The gate stops new signing before the deletion completes; the fate of an address already issued and not yet expired is not established by the code.

What this costs a seller who does not know it

Each of these follows from treating a signed address as if it were a name.

  • A published listing quietly loses its photograph after the hour is up.

    Point the listing at an image the destination holds. Use the signed address only for looking, never as a source.

  • A customer is told an image is unreachable on the strength of a deletion request, and the claim is wider than the evidence.

    Report the part that is settled — no new address will be signed — and say nothing about an address already sent.

  • A channel that cares about file format is trusted with an extension read off the address.

    Treat the extension as the type that was declared, not as the format that was measured, and confirm from the file when it matters.

  • An expiring address is described to a customer as a privacy or security measure.

    Do not make that claim. The lifetimes are how the addresses are issued; nothing read here establishes who can use one while it is valid.

Before you paste an image address anywhere

  • Decide whether the destination has to display the image from now on, or only has to see it once.
  • Count the hour from when the address was signed, not from when you pasted it.
  • Keep your own records against the piece, not against the address or the object name.
  • Do not read the extension at the end of the address as the file's real format.
  • Do not describe the expiry to a customer as a privacy or access measure.
  • If the image has been queued for deletion, say only that no new address will be issued for it.

What this page does not settle

These are outside what the code read for this page establishes, so no answer is offered.

  • Who can use a signed address while it is still valid. Expiry is not offered here as an access measure.
  • What happens to an address that was signed before an image entered the deletion queue and has not yet expired.
  • What happens to an upload that starts inside the fifteen-minute window and finishes after it.
  • How any other screen in the app handles its addresses. The model catalogue is the only client surface whose address handling was read for this page.
  • What is sent to the AI provider when you submit a generation — a separate subject, not answered here.
  • What becomes of an upload you start and then never use in a generation — also a separate subject.
  • The format, transparency and pixel size of the file a generation returns; those are decided elsewhere in the product and are not established by the code this page rests on.

Questions

Can I copy a link to my generated image and paste it into a listing?

You can copy it, but a viewing address is signed for one hour (an expiry of 3600 seconds in apps/api/src/storage/storage.service.ts), so a listing pointed at it is pointed at something that stops resolving. If the listing has to display the image from now on, the image has to sit where the listing serves it from.

Why did the image load an hour ago and not now?

The address you kept was signed with a one-hour life, and that permission has run out. Nothing about the stored image has to have changed for this to happen; a fresh address is a fresh permission for the same object.

My upload was still running at fifteen minutes. Did the limit stop it?

Fifteen minutes is how long the upload address stays valid (PRESIGN_PUT_EXPIRES_SEC is 900 seconds), not how long the transfer may take. What happens to a transfer that starts inside the window and finishes after it cannot be read from the code, so this page cannot tell you the window is what stopped it.

I deleted an image. Does the link I already sent someone stop working?

Once the image is queued for deletion the server stops signing new viewing addresses for it, and it stops before the deletion has finished. What happens to an address that was already signed and has not yet expired is not something the code settles — so say that the app will issue no new address for the image, rather than that the old one is dead.