Skip to content

Diagrams

Every diagram in these docs, in the order to read them. Each one also sits on the page that explains it, linked under its heading. Every diagram has a text version: open "Read this diagram as text".

MarkMeaning
A box outlined in inkYours: your page or your backend
A filled boxFlume's: the iframe or Flume's servers
A capsuleA person, or a state
A thick solid arrowA server call over HTTPS
A dashed arrowA postMessage between the iframe and your page
A thin grey arrowA call the iframe makes on its own
A dotted arrowSomething a person does

From the overview.

Two ways to integrate, side by sideWith the iframe, Flume draws the screens and your backend makes two calls. With the API, you draw them and your backend makes every call. The same content is listed as text under the diagram.Embed the iframe (recommended)Call the APIFlume iframeverify, search, quote, saveYour pageframes it, handles messagesYour backend2 server callsYour screensyou build each oneYour backendthe six API stepsFlume serversPartner API4 messages2 repliesyour routesyour routesevery stepYoursFlume'sServer call (HTTPS)postMessage

Two ways to integrate, side by side. With the iframe, Flume draws the screens and your backend makes two calls. With the API, you draw them and your backend makes every call.

Read this diagram as text
  1. Embed the iframe, recommended: Flume draws the verify, search, quote and save screens inside an iframe.
  2. Your page frames the iframe and handles its messages: four from the iframe, two replies from your page.
  3. Your backend makes two server calls: start a session, and exchange a connect code.
  4. Call the API: you build every screen yourself.
  5. Your backend makes every call to the Partner API, in six steps: verify (two calls), search by photo, product detail, instant quote, and a link into Flume.
  6. Both use the same partner key, users and save payload, and you can combine them.

From the overview.

Who talks to whomFour parts and one person. Your page and the Flume iframe share the browser. Only your backend calls Flume with your key. The same content is listed as text under the diagram.In the browserOn serversUserYour pageframes the iframeYour backendholds the partner keyFlume iframedraws every screenFlume serversclickssearches,prices, savesyour routesserver calls,partner keypostMessage:4 to you, 2 backits own callsYoursFlume'sServer call (HTTPS)postMessageThe iframe's own callA person acts

Who talks to whom. Four parts and one person. Your page and the Flume iframe share the browser. Only your backend calls Flume with your key.

Read this diagram as text
  1. The user clicks a button on your page.
  2. Your page calls your own backend. It never calls Flume.
  3. Your backend calls Flume over HTTPS, with your partner key. These are the server calls.
  4. Your page frames the Flume iframe. The two talk only with postMessage: four message types from the iframe, two from your page.
  5. The user searches, prices and saves inside the iframe. The iframe makes its own calls to Flume with its own short-lived credential.
  6. Your partner key and user access tokens stay on your backend. They never reach the browser.

From Get a sandbox key.

From a key to live, step by stepThe order to build in. Each step has a page. The same content is listed as text under the diagram.1. Get a sandbox keyand an allowed origin2. Start a sessionyour backend3. Mount the iframetag and host snippet4. Exchange the codestore the user token5. Write the saved itemonce per save_uuid6. Close, expiry, errorsevery message handled7. Go-live checklistin the sandbox8. Ask for live accessthen switch URL and keyYoursFlume's

From a key to live, step by step. The order to build in. Each step has a page.

Read this diagram as text
  1. Get a sandbox key, and have Flume set your page origin as an allowed origin.
  2. Start a session from your backend with POST /start-iframe-session.
  3. Mount the iframe on your page: the iframe tag and the host snippet.
  4. Exchange the connect code on your backend and store the user access token.
  5. Write the saved item, once per save_uuid, and reply to the iframe.
  6. Handle close, expiry, the ready timer and errors.
  7. Finish the go-live checklist in the sandbox.
  8. Ask Flume for live access, then switch the base URL and the key.

From the API quickstart.

The API path: six stepsAn API integration makes these six calls, in this order. Every call carries the partner key; steps 3 to 6 also carry the user access token. The same content is listed as text under the diagram.Your backendFlume servers1POST /users/trigger-verification2POST /users/confirm-verification3POST /search4GET /products/{sku_uuid}5POST /request-instant-quote6POST /deep-linksServer call (HTTPS)

The API path: six steps. An API integration makes these six calls, in this order. Every call carries the partner key; steps 3 to 6 also carry the user access token.

Read this diagram as text
  1. Verify a user, send the code: POST /users/trigger-verification. Flume emails the user a 6-digit code.
  2. Verify a user, confirm the code: POST /users/confirm-verification returns the user access token.
  3. Search by photo: POST /search returns two lists and a search_session_uuid. GET /filters lists the filter options.
  4. Product detail: GET /products/{sku_uuid} returns photos, price, specification and shipping.
  5. Instant quote: POST /request-instant-quote returns the delivered price. A quote that is still pricing is read with GET /quotes/{quote_uuid}.
  6. Open Flume, signed in: POST /deep-links returns a one-time link into the user's Flume account.

From Verify a user and Find products by photo.

Steps 1 and 2: verify a user through the APIYou build the code screen. Two calls, with the partner key only. The second returns the user access token. The same content is listed as text under the diagram.UserYour pageYour backendFlume servers1email2POST /users/trigger-verification3email, 6 digits4types the code5code6POST /users/confirm-verification7access_token8store the tokenServer call (HTTPS)A person actsAny other step

Steps 1 and 2: verify a user through the API. You build the code screen. Two calls, with the partner key only. The second returns the user access token.

Read this diagram as text
  1. Your screen sends the user's email to your backend.
  2. Your backend calls POST /users/trigger-verification with external_ref and email.
  3. Flume emails the user a 6-digit code, valid for 10 minutes.
  4. The user types the code on your screen.
  5. Your screen sends the code to your backend.
  6. Your backend calls POST /users/confirm-verification with the email and the code.
  7. Flume returns the user access token, once.
  8. Your backend stores the token against that user and sends it on every call made for them.

From How the iframe works.

The whole flow, from a click to a saved itemOne open of the iframe, end to end. Lighter steps happen only the first time a user opens it. The same content is listed as text under the diagram.Flume iframeYour pageYour backendFlume servers1open item2POST /start-iframe-session3iframe_url, session_uuid4iframe_url, session_uuid5iframe.src = iframe_url6flume:iframe_ready7flume:user_connected8connect_code9POST /users/exchange-connect-code10flume:save_item11flume:item_saved12flume:close_iframeServer call (HTTPS)postMessageAny other stepLighter: not every time

The whole flow, from a click to a saved item. One open of the iframe, end to end. Lighter steps happen only the first time a user opens it.

Read this diagram as text
  1. The user clicks your button. Your page asks your backend to start a session.
  2. Your backend calls POST /start-iframe-session with the user, project and item.
  3. Flume returns iframe_url and session_uuid.
  4. Your backend passes both to your page.
  5. Your page starts the ready timer, adds the message listener, then sets the iframe src.
  6. The iframe posts flume:iframe_ready. Your page clears the timer.
  7. First time only: the user verifies their email, and the iframe posts flume:user_connected with a connect code.
  8. First time only: your page sends the connect code to your backend.
  9. First time only: your backend exchanges the code for the user access token and stores it.
  10. The user saves a product. The iframe posts flume:save_item with the save payload.
  11. Your page writes its record and replies flume:item_saved, or flume:item_save_failed.
  12. The iframe posts flume:close_iframe. Your page removes the iframe.

From Messages.

Every message, and which way it goesAll six postMessage types between the iframe and your page, in the order one open usually sends them. Four come to your page, two go back. The same content is listed as text under the diagram.Flume iframeYour page1flume:iframe_ready2flume:user_connected3flume:save_item4flume:item_saved5flume:item_save_failed6flume:close_iframepostMessageLighter: not every time

Every message, and which way it goes. All six postMessage types between the iframe and your page, in the order one open usually sends them. Four come to your page, two go back.

Read this diagram as text
  1. The iframe posts flume:iframe_ready once it has painted, with an empty payload. Clear the ready timer and show the iframe.
  2. First open only: the iframe posts flume:user_connected with a connect_code. Send it to your backend at once. The iframe expects no reply.
  3. The iframe posts flume:save_item with the save payload, which carries save_uuid. It waits 60 seconds for your reply.
  4. Your page replies flume:item_saved with the same save_uuid, and item_ref and item_label when you have them.
  5. Or your page replies flume:item_save_failed with the same save_uuid and a reason: permission, conflict, storage or error.
  6. The iframe posts flume:close_iframe with a reason of done, closed or expired. Remove the iframe. On expired, start a new session.

From Server calls.

Start a session and mount the iframeFrom the click to a loaded iframe. A user access token, when you hold one, skips the email step. The same content is listed as text under the diagram.UserFlume iframeYour pageYour backendFlume servers1clicks your button2your route3POST /start-iframe-session4iframe_url, session_uuid5iframe_url, session_uuid6ready timer, 15 s7iframe.src8launch code, once9flume:iframe_readyServer call (HTTPS)postMessageThe iframe's own callA person actsAny other step

Start a session and mount the iframe. From the click to a loaded iframe. A user access token, when you hold one, skips the email step.

Read this diagram as text
  1. The user clicks your button for one item.
  2. Your page asks your backend to start a session.
  3. Your backend calls POST /start-iframe-session with the user, project, item and host_origin. It sends the stored user access token when it holds one.
  4. Flume returns iframe_url and session_uuid.
  5. Your backend returns only those two values to your page.
  6. Your page starts a ready timer of 15 seconds and adds the message listener.
  7. Your page sets iframe_url as the iframe src, at once.
  8. The iframe spends the launch code with Flume. It works once, within 120 seconds.
  9. The iframe posts flume:iframe_ready. Your page clears the timer and hides its spinner. The iframe also posts it when it could not start: it then shows its own error, and its Try again posts flume:close_iframe with reason expired.

From Users and verification.

The first open: the user verifies, you get a tokenHappens once per user. You build no screen for it: the iframe asks for the code. The same content is listed as text under the diagram.UserFlume iframeYour pageYour backendFlume servers1clicks Connect2send a code3email, 6 digits4types the code5check the code6flume:user_connected7connect_code8POST /users/exchange-connect-code9access_token10store the tokenServer call (HTTPS)postMessageThe iframe's own callA person actsAny other step

The first open: the user verifies, you get a token. Happens once per user. You build no screen for it: the iframe asks for the code.

Read this diagram as text
  1. The iframe opened without a user access token, so it shows the user their name and email. The user clicks Connect.
  2. The iframe asks Flume to email a code.
  3. Flume emails a 6-digit code to the user. It is valid for 10 minutes.
  4. The user types the code in the iframe.
  5. The iframe checks the code with Flume. Any token you held for this user stops working now.
  6. The iframe posts flume:user_connected with a connect code.
  7. Your page sends the connect code to your backend, at once.
  8. Your backend calls POST /users/exchange-connect-code. The code works once, within 120 seconds.
  9. Flume returns the user access token, once.
  10. Your backend checks external_ref, then stores the token over any older one. It sends it on the next POST /start-iframe-session.

From Users and verification.

A later open, for a user whose token you holdNo email step and no flume:user_connected. Lighter steps happen only when the stored token has stopped working. The same content is listed as text under the diagram.UserFlume iframeYour pageYour backendFlume servers1clicks your button2your route3POST /start-iframe-session4401 USER_TOKEN_INVALID5delete the token6POST /start-iframe-session7iframe_url, session_uuid8iframe_url, session_uuid9iframe.src10launch code, once11flume:iframe_readyServer call (HTTPS)postMessageThe iframe's own callA person actsAny other stepLighter: not every time

A later open, for a user whose token you hold. No email step and no flume:user_connected. Lighter steps happen only when the stored token has stopped working.

Read this diagram as text
  1. The user clicks your button for one item.
  2. Your page asks your backend to start a session.
  3. Your backend calls POST /start-iframe-session and sends the user access token it stored for this user.
  4. Only when the token no longer works, because the user verified again or you revoked it: Flume answers 401 USER_TOKEN_INVALID.
  5. Then your backend deletes the stored token.
  6. Then your backend calls POST /start-iframe-session again without a token. The user verifies in the iframe, as on a first open.
  7. Flume returns iframe_url and session_uuid.
  8. Your backend returns those two values to your page.
  9. Your page starts the ready timer, adds the message listener and sets the iframe src.
  10. The iframe spends the launch code with Flume.
  11. The iframe posts flume:iframe_ready and opens with the user already verified.

From Save payload and Messages.

Save an itemThe user saves in the iframe, your side writes the record, and your page answers. Your backend calls Flume at no point. The same content is listed as text under the diagram.UserFlume iframeYour pageYour backendFlume servers1confirms a save2build the save payload3flume:save_item4save payload5write once per save_uuid6your record id7flume:item_saved8record the result9saved screenpostMessageThe iframe's own callA person actsAny other step

Save an item. The user saves in the iframe, your side writes the record, and your page answers. Your backend calls Flume at no point.

Read this diagram as text
  1. The user confirms a save in the iframe.
  2. The iframe asks Flume for the save payload. If that fails, the iframe shows its own error and your page hears nothing.
  3. The iframe posts flume:save_item with the save payload and its save_uuid.
  4. Your page sends the payload to your backend.
  5. Your backend writes one record per save_uuid, and copies the photo bytes if you keep a photo.
  6. Your backend answers with your record, or with a failure.
  7. Your page replies flume:item_saved with the same save_uuid, within 60 seconds. On a failed write it replies flume:item_save_failed instead.
  8. The iframe tells Flume how the save ended. You make no call for this.
  9. The iframe shows the saved screen.
Every way a save can endThree outcomes of one flume:save_item. Two of them show the user the same message, and a retry repeats the same save_uuid. The same content is listed as text under the diagram.flume:save_itemcarries save_uuidflume:item_savedyour write workedflume:item_save_failedpermission, conflict,storage or errorNo replywithin 60 secondsSaved screenshows item_labelCould not saveClose, or Try again

Every way a save can end. Three outcomes of one flume:save_item. Two of them show the user the same message, and a retry repeats the same save_uuid.

Read this diagram as text
  1. The iframe posts flume:save_item with a save_uuid.
  2. Your page replies flume:item_saved: the user sees the saved screen, with your item_label when you send one.
  3. Your page replies flume:item_save_failed with a reason of permission, conflict, storage or error: the user sees one message with Close and Try again. The reason is not shown.
  4. Your page does not reply within 60 seconds: the user sees the same message.
  5. Try again posts flume:save_item again with the same save_uuid. Your write must be safe to repeat.

From Server calls.

Open in Flume, for a saved itemOptional. A one-time link, created on the click and never stored. The same content is listed as text under the diagram.UserYour pageYour backendFlume servers1clicks Open in Flume2open a blank tab3your route4POST /deep-links5url6url7tab goes to the urlServer call (HTTPS)A person actsAny other step

Open in Flume, for a saved item. Optional. A one-time link, created on the click and never stored.

Read this diagram as text
  1. The user clicks "Open in Flume" on a saved item.
  2. Your page opens a blank tab in the click handler, so the browser does not block it.
  3. Your page asks your backend for a link.
  4. Your backend calls POST /deep-links with the user access token, and the search_session_uuid and sku_uuid it kept from the save payload.
  5. Flume returns a link that works once, within 7 days.
  6. Your backend returns the link. It stores it nowhere.
  7. Your page points the tab at the link. Flume opens with the user signed in. With no token, link to product_url instead.

From Set up your page.

The iframe on your page, state by stateWhat your page is doing at each moment, and the message or timer that moves it on. The same content is listed as text under the diagram.Failed to loadStartingExpiredExchangingReadyClosedSavingready timer,15 suser retriesflume:iframe_readyflume:user_connectedtoken storedflume:save_itemreply, or 60 sflume:close_iframedone or closedflume:close_iframeexpirednew sessionpostMessageA person acts

The iframe on your page, state by state. What your page is doing at each moment, and the message or timer that moves it on.

Read this diagram as text
  1. Starting: your page set the iframe src and runs a ready timer of 15 seconds. Before that, nothing is mounted.
  2. Starting to Ready: flume:iframe_ready arrives. Clear the timer.
  3. Starting to Failed to load: the timer fires first. Remove the iframe and show an error with a retry. A retry starts a new session.
  4. Ready to Exchanging and back: flume:user_connected arrives, your backend exchanges the connect code and stores the token. The iframe does not wait for it.
  5. Ready to Saving and back: flume:save_item arrives, and your page replies. After 60 seconds without a reply the iframe treats the save as failed.
  6. Ready to Closed: flume:close_iframe with reason done or closed. Remove the iframe.
  7. Ready to Expired: flume:close_iframe with reason expired. Start a new session and mount again.
  8. flume:close_iframe can arrive at any moment after Starting, also while a save or an exchange is running. Remove the iframe all the same.
  9. An iframe that could not start still posts flume:iframe_ready, shows its own error, and posts flume:close_iframe with reason expired when the user asks to try again.

From Security and CSP.

Where each secret lives and travelsLong-lived secrets stay on servers. Only single-use, short-lived codes pass through the browser. The same content is listed as text under the diagram.Browser: single-use codes onlyServers: secrets stay hereYour pagechecks origin, source,version, session_uuidYour backendpartner keyuser access tokensFlume iframeposts only to host_originits own short credentialFlume serversallowed originsper partneriframe_url (launch code)connect_codepartner key,user access tokeniframe_url,access_tokensave repliesconnect_code,save payloadlaunch code, onceYoursFlume'sServer call (HTTPS)postMessageThe iframe's own call

Where each secret lives and travels. Long-lived secrets stay on servers. Only single-use, short-lived codes pass through the browser.

Read this diagram as text
  1. Your backend holds the partner key and each user access token. It sends them only to Flume, over HTTPS.
  2. Flume returns iframe_url, which carries a launch code. The launch code works once, within 120 seconds.
  3. Your backend hands iframe_url to your page. Your page sets it as the iframe src and stores it nowhere.
  4. The iframe spends the launch code with Flume and then uses its own short-lived credential.
  5. When a user verifies, the iframe posts a connect code to your page. It works once, within 120 seconds.
  6. Your page passes the connect code to your backend, which exchanges it for the user access token.
  7. Your page accepts a message only when its origin, source, version and session_uuid are right. The iframe posts only to the host_origin you sent.

From How the iframe works.

What you store, and what you never storeTwo things are worth keeping. Everything else is used once and dropped. The same content is listed as text under the diagram.Store, on your serverUse once, never storeExchange responsePOST /users/exchange-connect-codeflume:save_itemthe save payloadSession responsePOST /start-iframe-sessionflume:user_connectedUser access tokenper external_ref, encryptedYour saved itemkeyed by save_uuid: your fields,photo bytes, product_url, two idsiframe_urlset as the iframe src at onceconnect_codeexchange at onceaccess_tokenmapped fieldsuse onceuse once

What you store, and what you never store. Two things are worth keeping. Everything else is used once and dropped.

Read this diagram as text
  1. From the exchange response, store the user access token, per external_ref, encrypted, on your server.
  2. From flume:save_item, store your own record keyed by save_uuid: the fields you map, the photo bytes, product_url, and the two ids an Open in Flume link needs (match.search_session_uuid and product.sku_uuid).
  3. Never store iframe_url or its launch code. Set it as the iframe src at once.
  4. Never store a connect code. Exchange it at once.
  5. Also never store image links or an Open in Flume link: both expire. Log session_uuid with your item id and user id.

From Limits.

How long each thing lastsEvery timer, code and link in the integration, shortest first. The scale is logarithmic. The same content is listed as text under the diagram.ShorterLongerReady timer15 secondsReply to a save60 secondsLaunch code120 seconds, one useConnect code120 seconds, one useVerification code10 minutesIframe session12 hoursImage linksabout 24 hoursOpen in Flume link7 days, one useInstant quote prices30 daysUnused session30 daysUser access tokenno expiry

How long each thing lasts. Every timer, code and link in the integration, shortest first. The scale is logarithmic.

Read this diagram as text
  1. Ready timer: 15 seconds. On your page. When it fires, remove the iframe and offer a retry.
  2. Reply to a save: 60 seconds. After that the iframe treats the save as failed.
  3. Launch code: 120 seconds, one use. Inside iframe_url. Set the iframe src at once.
  4. Connect code: 120 seconds, one use. Exchange it at once.
  5. Verification code: 10 minutes. The emailed code the user types in the iframe.
  6. Iframe session: 12 hours. From its first open. Then flume:close_iframe with reason expired.
  7. Image links: about 24 hours. In the save payload. Copy the bytes when you save.
  8. Open in Flume link: 7 days, one use. Create it on the click. Never store it.
  9. Instant quote prices: 30 days. Until pricing.valid_until in the save payload.
  10. Unused session: 30 days. A session nobody reopens is dropped. The next open starts fresh.
  11. User access token: no expiry. Replaced when the user verifies again, or revoked by you.

From Handle errors.

What to do when a server call failsRead the status and error.code on the left, then take the one action beside it. The same content is listed as text under the diagram.401 PARTNER_KEY_INVALIDFix the key or the base URLdo not retry401 USER_TOKEN_INVALIDDelete the stored tokenstart again without it401 CONNECT_CODE_INVALIDStore nothingthe user verifies on the next open403 USER_NOT_CONNECTEDVerify the userthen send the user access token400, 404, 413, 422and any other 403 or 409Fix the requestfield names what is wrong409 IDEMPOTENCY_IN_PROGRESSRetry with the same keyafter Retry-After429Wait for Retry-After, then retrya daily limit resets at 00:00 UTC500, 502, 503, timeoutRetry with a growing waitsame Idempotency-Key, up to 3 retries

What to do when a server call fails. Read the status and error.code on the left, then take the one action beside it.

Read this diagram as text
  1. 401 PARTNER_KEY_INVALID: fix the key, or the base URL it belongs to. Do not retry.
  2. 401 USER_TOKEN_INVALID: delete the stored token and start the session again without it. The user verifies again in the iframe.
  3. 401 CONNECT_CODE_INVALID: store nothing and do not retry. The user verifies again on the next open.
  4. 403 USER_NOT_CONNECTED: the call needs a verified user. Verify the user, then send the user access token.
  5. 400, 404, 413, 422, and any other 403 or 409: fix the request. On a 422, field names what is wrong. Do not retry unchanged.
  6. 409 IDEMPOTENCY_IN_PROGRESS: the first request with this Idempotency-Key is still running. Retry with the same key after Retry-After.
  7. 429: wait for the number of seconds in Retry-After, then retry. For a daily limit that is the time until 00:00 UTC, so stop for the day.
  8. 500, 502, 503 or a timeout: retry with a growing wait and the same Idempotency-Key, up to 3 retries.