API referenceAdmin previews

Admin previews

9 operations. Every schema and example on this page is generated from the platform contract.

Previews: list and funnel.

Internal-admin. Previews made in the range (newest first, 200 at most) with their status, photos as 1-hour signed links, and the funnel (created > sent > opened > Make it mine > claimed > live) split by channel and preview type. Test previews are left out unless include_test. Expired previews are purged on the way in.

Parameters

rangeenumqueryoptional

Previews made in the last N days. Default 30d.

7d30d90d365d
channelenumqueryoptional
cold_dmcomment_replycategory_pagein_personadasked_first
include_testbooleanqueryoptional

Include test previews. Default false.

Response, 200

previewsarray of objectrequired
24 child fields
idstringrequired
urlstringrequired
ig_handlestringrequired
shop_namestringrequired
kindstringrequired
channelenumrequired
cold_dmcomment_replycategory_pagein_personadasked_first
itemsarray of objectrequired
4 child fields
namestringrequired
price_pencenumber, nullablerequired
price_from_captionbooleanrequired
photo_idstring, nullablerequired
is_testbooleanrequired
statusenumrequired
draftsentopenedclaimedliveexpired
preview_typeenumrequired
name_onlywith_photos
expires_atstringrequired
expires_in_daysnumber, nullablerequired
created_atstringrequired
updated_atstringrequired
sent_atstring, nullablerequired
followed_up_atstring, nullablerequired
first_opened_atstring, nullablerequired
last_opened_atstring, nullablerequired
open_countnumberrequired
claimed_atstring, nullablerequired
claimed_store_idstring, nullablerequired
ownership_verified_atstring, nullablerequired
claim_undone_atstring, nullablerequired
photosarray of objectrequired
7 child fields
idstringrequired
roleenumrequired
logoproduct
sortnumberrequired
widthnumber, nullablerequired
heightnumber, nullablerequired
urlstring, nullablerequired
created_atstringrequired
truncatedbooleanrequired
funnelobjectrequired
7 child fields
fromstringrequired
tostringrequired
include_testbooleanrequired
stagesarray of objectrequired
4 child fields
stageenumrequired
createdmarked_sentopenedmake_it_mine_tappedclaimedlive
previewsnumberrequired
of_previousnumber, nullablerequired
of_creatednumber, nullablerequired
by_channelarray of objectrequired
2 child fields
channelenumrequired
cold_dmcomment_replycategory_pagein_personadasked_first
stagesarray of objectrequired
4 child fields
stageenumrequired
createdmarked_sentopenedmake_it_mine_tappedclaimedlive
previewsnumberrequired
of_previousnumber, nullablerequired
of_creatednumber, nullablerequired
by_preview_typearray of objectrequired
2 child fields
preview_typeenumrequired
name_onlywith_photos
stagesarray of objectrequired
4 child fields
stageenumrequired
createdmarked_sentopenedmake_it_mine_tappedclaimedlive
previewsnumberrequired
of_previousnumber, nullablerequired
of_creatednumber, nullablerequired
outcomesobjectrequired
5 child fields
not_for_menumberrequired
not_for_me_reasonsobjectrequired
4 child fields
not_selling_nownumberrequired
happy_with_dmsnumberrequired
use_something_elsenumberrequired
nonenumberrequired
expirednumberrequired
deletednumberrequired
do_not_contactnumberrequired
curl -G "https://www.membber.com/api/v1/admin-previews" \
  -H "Authorization: Bearer $MEMBBER_TOKEN"
Response, 200
{
  "previews": [
    {
      "id": "00000d1b-0000-4000-8000-d0c500000000",
      "url": "https://example.com/image.jpg",
      "ig_handle": "<ig_handle>",
      "shop_name": "<shop_name>",
      "kind": "<kind>",
      "channel": "cold_dm",
      "items": [
        {
          "name": "Example name",
          "price_pence": 1500,
          "price_from_caption": true,
          "photo_id": "b40c2e48-0000-4000-8000-d0c5000000b4"
        }
      ],
      "is_test": true,
      "status": "draft",
      "preview_type": "name_only",
      "expires_at": "<expires_at>",
      "expires_in_days": 1,
      "created_at": "<created_at>",
      "updated_at": "<updated_at>",
      "sent_at": "<sent_at>",
      "followed_up_at": "<followed_up_at>",
      "first_opened_at": "<first_opened_at>",
      "last_opened_at": "<last_opened_at>",
      "open_count": 1,
      "claimed_at": "<claimed_at>",
      "claimed_store_id": "6a0dc31d-0000-4000-8000-d0c50000006a",
      "ownership_verified_at": "<ownership_verified_at>",
      "claim_undone_at": "<claim_undone_at>",
      "photos": [
        {
          "id": "00000d1b-0000-4000-8000-d0c500000000",
          "role": "logo",
          "sort": 1,
          "width": 1,
          "height": 1,
          "url": "https://example.com/image.jpg",
          "created_at": "<created_at>"
        }
      ]
    }
  ],
  "truncated": true,
  "funnel": {
    "from": "<from>",
    "to": "<to>",
    "include_test": true,
    "stages": [
      {
        "stage": "created",
        "previews": 1,
        "of_previous": 1,
        "of_created": 1
      }
    ],
    "by_channel": [
      {
        "channel": "cold_dm",
        "stages": [
          {
            "stage": "created",
            "previews": 1,
            "of_previous": 1,
            "of_created": 1
          }
        ]
      }
    ],
    "by_preview_type": [
      {
        "preview_type": "name_only",
        "stages": [
          {
            "stage": "created",
            "previews": 1,
            "of_previous": 1,
            "of_created": 1
          }
        ]
      }
    ],
    "outcomes": {
      "not_for_me": 1,
      "not_for_me_reasons": {
        "not_selling_now": 1,
        "happy_with_dms": 1,
        "use_something_else": 1,
        "none": 1
      },
      "expired": 1,
      "deleted": 1,
      "do_not_contact": 1
    }
  }
}

Previews: make one.

Internal-admin. Refuses a handle on the do-not-contact list (409 DO_NOT_CONTACT, with the date) and a second unclaimed preview for the same handle (409 PREVIEW_EXISTS, with its id). Send an Idempotency-Key (UUID) header: a retry with the same key returns the same preview.

Request body

ig_handlestringrequired

Her Instagram handle, with or without @, or her profile link.

shop_namestringrequired
kindenumrequired
cookiescakescinnamon-bunspizzatakeawaymeal-prepfish-and-chipscoffeestreetwearbrowniescheesecakesflowerschristmascake-shedsmarket-stallsbutchersfood-vansother
channelenumrequired
cold_dmcomment_replycategory_pagein_personadasked_first
itemsarray of objectoptional

Up to 3. No photo_id yet: photos are added after the preview exists.

4 child fields
namestringrequired
price_penceinteger, nullablerequired
price_from_captionbooleanrequired
photo_idstring · uuid, nullablerequired
is_testbooleanoptional

A test preview (a fake handle), left out of the funnel.

Response, 200

previewobjectrequired
24 child fields
idstringrequired
urlstringrequired
ig_handlestringrequired
shop_namestringrequired
kindstringrequired
channelenumrequired
cold_dmcomment_replycategory_pagein_personadasked_first
itemsarray of objectrequired
4 child fields
namestringrequired
price_pencenumber, nullablerequired
price_from_captionbooleanrequired
photo_idstring, nullablerequired
is_testbooleanrequired
statusenumrequired
draftsentopenedclaimedliveexpired
preview_typeenumrequired
name_onlywith_photos
expires_atstringrequired
expires_in_daysnumber, nullablerequired
created_atstringrequired
updated_atstringrequired
sent_atstring, nullablerequired
followed_up_atstring, nullablerequired
first_opened_atstring, nullablerequired
last_opened_atstring, nullablerequired
open_countnumberrequired
claimed_atstring, nullablerequired
claimed_store_idstring, nullablerequired
ownership_verified_atstring, nullablerequired
claim_undone_atstring, nullablerequired
photosarray of objectrequired
7 child fields
idstringrequired
roleenumrequired
logoproduct
sortnumberrequired
widthnumber, nullablerequired
heightnumber, nullablerequired
urlstring, nullablerequired
created_atstringrequired
curl -X POST "https://www.membber.com/api/v1/admin-previews" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "ig_handle": "<ig_handle>",
    "shop_name": "<shop_name>",
    "kind": "cookies",
    "channel": "cold_dm"
  }'
Response, 200
{
  "preview": {
    "id": "00000d1b-0000-4000-8000-d0c500000000",
    "url": "https://example.com/image.jpg",
    "ig_handle": "<ig_handle>",
    "shop_name": "<shop_name>",
    "kind": "<kind>",
    "channel": "cold_dm",
    "items": [
      {
        "name": "Example name",
        "price_pence": 1500,
        "price_from_caption": true,
        "photo_id": "b40c2e48-0000-4000-8000-d0c5000000b4"
      }
    ],
    "is_test": true,
    "status": "draft",
    "preview_type": "name_only",
    "expires_at": "<expires_at>",
    "expires_in_days": 1,
    "created_at": "<created_at>",
    "updated_at": "<updated_at>",
    "sent_at": "<sent_at>",
    "followed_up_at": "<followed_up_at>",
    "first_opened_at": "<first_opened_at>",
    "last_opened_at": "<last_opened_at>",
    "open_count": 1,
    "claimed_at": "<claimed_at>",
    "claimed_store_id": "6a0dc31d-0000-4000-8000-d0c50000006a",
    "ownership_verified_at": "<ownership_verified_at>",
    "claim_undone_at": "<claim_undone_at>",
    "photos": [
      {
        "id": "00000d1b-0000-4000-8000-d0c500000000",
        "role": "logo",
        "sort": 1,
        "width": 1,
        "height": 1,
        "url": "https://example.com/image.jpg",
        "created_at": "<created_at>"
      }
    ]
  }
}

Previews: delete one now.

Internal-admin. Deletes an unclaimed preview, its photo rows and its stored photos. The funnel keeps an anonymous "deleted" event. A claimed preview is refused (409 PREVIEW_CLAIMED).

Parameters

previewIdstringpathrequired

Response, 200

deletedbooleanrequired
idstringrequired
curl -X DELETE "https://www.membber.com/api/v1/admin-previews/ce5f1b03-0000-4000-8000-d0c5000000ce" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678"
Response, 200
{
  "deleted": true,
  "id": "00000d1b-0000-4000-8000-d0c500000000"
}

Previews: edit one, or mark it sent / followed up.

Internal-admin. Edits are refused once she has claimed it (409 PREVIEW_CLAIMED). A follow-up needs a send first (409 NOT_SENT), and there is only ever one.

Parameters

previewIdstringpathrequired

Request body

shop_namestringoptional
kindenumoptional
cookiescakescinnamon-bunspizzatakeawaymeal-prepfish-and-chipscoffeestreetwearbrowniescheesecakesflowerschristmascake-shedsmarket-stallsbutchersfood-vansother
channelenumoptional
cold_dmcomment_replycategory_pagein_personadasked_first
itemsarray of objectoptional
4 child fields
namestringrequired
price_penceinteger, nullablerequired
price_from_captionbooleanrequired
photo_idstring · uuid, nullablerequired
markenumoptional

Record that the founder sent the link, or sent the one follow-up. Repeats are no-ops.

sentfollowed_up

Response, 200

previewobjectrequired
24 child fields
idstringrequired
urlstringrequired
ig_handlestringrequired
shop_namestringrequired
kindstringrequired
channelenumrequired
cold_dmcomment_replycategory_pagein_personadasked_first
itemsarray of objectrequired
4 child fields
namestringrequired
price_pencenumber, nullablerequired
price_from_captionbooleanrequired
photo_idstring, nullablerequired
is_testbooleanrequired
statusenumrequired
draftsentopenedclaimedliveexpired
preview_typeenumrequired
name_onlywith_photos
expires_atstringrequired
expires_in_daysnumber, nullablerequired
created_atstringrequired
updated_atstringrequired
sent_atstring, nullablerequired
followed_up_atstring, nullablerequired
first_opened_atstring, nullablerequired
last_opened_atstring, nullablerequired
open_countnumberrequired
claimed_atstring, nullablerequired
claimed_store_idstring, nullablerequired
ownership_verified_atstring, nullablerequired
claim_undone_atstring, nullablerequired
photosarray of objectrequired
7 child fields
idstringrequired
roleenumrequired
logoproduct
sortnumberrequired
widthnumber, nullablerequired
heightnumber, nullablerequired
urlstring, nullablerequired
created_atstringrequired
curl -X PATCH "https://www.membber.com/api/v1/admin-previews/ce5f1b03-0000-4000-8000-d0c5000000ce" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "shop_name": "<shop_name>",
    "kind": "cookies",
    "channel": "cold_dm",
    "items": [
      {
        "name": "Example name",
        "price_pence": 1500,
        "price_from_caption": true,
        "photo_id": "b40c2e48-0000-4000-8000-d0c5000000b4"
      }
    ],
    "mark": "sent"
  }'
Response, 200
{
  "preview": {
    "id": "00000d1b-0000-4000-8000-d0c500000000",
    "url": "https://example.com/image.jpg",
    "ig_handle": "<ig_handle>",
    "shop_name": "<shop_name>",
    "kind": "<kind>",
    "channel": "cold_dm",
    "items": [
      {
        "name": "Example name",
        "price_pence": 1500,
        "price_from_caption": true,
        "photo_id": "b40c2e48-0000-4000-8000-d0c5000000b4"
      }
    ],
    "is_test": true,
    "status": "draft",
    "preview_type": "name_only",
    "expires_at": "<expires_at>",
    "expires_in_days": 1,
    "created_at": "<created_at>",
    "updated_at": "<updated_at>",
    "sent_at": "<sent_at>",
    "followed_up_at": "<followed_up_at>",
    "first_opened_at": "<first_opened_at>",
    "last_opened_at": "<last_opened_at>",
    "open_count": 1,
    "claimed_at": "<claimed_at>",
    "claimed_store_id": "6a0dc31d-0000-4000-8000-d0c50000006a",
    "ownership_verified_at": "<ownership_verified_at>",
    "claim_undone_at": "<claim_undone_at>",
    "photos": [
      {
        "id": "00000d1b-0000-4000-8000-d0c500000000",
        "role": "logo",
        "sort": 1,
        "width": 1,
        "height": 1,
        "url": "https://example.com/image.jpg",
        "created_at": "<created_at>"
      }
    ]
  }
}

Previews: get a one-use upload link for a photo.

Internal-admin. The path is minted by the server under previews/<previewId>/ in the PRIVATE bucket drops-previews. JPEG, PNG or WebP up to 5 MB. Refused when the role is already full (1 logo, 6 products).

Parameters

previewIdstringpathrequired

Request body

roleenumrequired
logoproduct
content_typeenumrequired
image/jpegimage/pngimage/webp
byte_sizeintegerrequired

Response, 200

pathstringrequired
tokenstringrequired
signed_urlstringrequired
curl -X POST "https://www.membber.com/api/v1/admin-previews/ce5f1b03-0000-4000-8000-d0c5000000ce/photos" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "role": "logo",
    "content_type": "image/jpeg",
    "byte_size": 1
  }'
Response, 200
{
  "path": "<path>",
  "token": "<token>",
  "signed_url": "https://example.com/image.jpg"
}

Previews: remove a photo.

Internal-admin. Removes the photo row and its stored object; an item that used it loses its photo.

Parameters

previewIdstringpathrequired
photoIdstringpathrequired

Response, 200

previewobjectrequired
24 child fields
idstringrequired
urlstringrequired
ig_handlestringrequired
shop_namestringrequired
kindstringrequired
channelenumrequired
cold_dmcomment_replycategory_pagein_personadasked_first
itemsarray of objectrequired
4 child fields
namestringrequired
price_pencenumber, nullablerequired
price_from_captionbooleanrequired
photo_idstring, nullablerequired
is_testbooleanrequired
statusenumrequired
draftsentopenedclaimedliveexpired
preview_typeenumrequired
name_onlywith_photos
expires_atstringrequired
expires_in_daysnumber, nullablerequired
created_atstringrequired
updated_atstringrequired
sent_atstring, nullablerequired
followed_up_atstring, nullablerequired
first_opened_atstring, nullablerequired
last_opened_atstring, nullablerequired
open_countnumberrequired
claimed_atstring, nullablerequired
claimed_store_idstring, nullablerequired
ownership_verified_atstring, nullablerequired
claim_undone_atstring, nullablerequired
photosarray of objectrequired
7 child fields
idstringrequired
roleenumrequired
logoproduct
sortnumberrequired
widthnumber, nullablerequired
heightnumber, nullablerequired
urlstring, nullablerequired
created_atstringrequired
curl -X DELETE "https://www.membber.com/api/v1/admin-previews/ce5f1b03-0000-4000-8000-d0c5000000ce/photos/dc8482ed-0000-4000-8000-d0c5000000dc" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678"
Response, 200
{
  "preview": {
    "id": "00000d1b-0000-4000-8000-d0c500000000",
    "url": "https://example.com/image.jpg",
    "ig_handle": "<ig_handle>",
    "shop_name": "<shop_name>",
    "kind": "<kind>",
    "channel": "cold_dm",
    "items": [
      {
        "name": "Example name",
        "price_pence": 1500,
        "price_from_caption": true,
        "photo_id": "b40c2e48-0000-4000-8000-d0c5000000b4"
      }
    ],
    "is_test": true,
    "status": "draft",
    "preview_type": "name_only",
    "expires_at": "<expires_at>",
    "expires_in_days": 1,
    "created_at": "<created_at>",
    "updated_at": "<updated_at>",
    "sent_at": "<sent_at>",
    "followed_up_at": "<followed_up_at>",
    "first_opened_at": "<first_opened_at>",
    "last_opened_at": "<last_opened_at>",
    "open_count": 1,
    "claimed_at": "<claimed_at>",
    "claimed_store_id": "6a0dc31d-0000-4000-8000-d0c50000006a",
    "ownership_verified_at": "<ownership_verified_at>",
    "claim_undone_at": "<claim_undone_at>",
    "photos": [
      {
        "id": "00000d1b-0000-4000-8000-d0c500000000",
        "role": "logo",
        "sort": 1,
        "width": 1,
        "height": 1,
        "url": "https://example.com/image.jpg",
        "created_at": "<created_at>"
      }
    ]
  }
}

Previews: attach an uploaded photo.

Internal-admin. Checks the stored object exists, is an allowed image type (by its first bytes, not only its declared type) and is within 5 MB, then attaches it (1 logo, 6 products). A bad or surplus upload is removed from storage. A retry with the same path returns the same preview.

Parameters

previewIdstringpathrequired

Request body

pathstringrequired
roleenumrequired
logoproduct
widthintegeroptional
heightintegeroptional

Response, 200

previewobjectrequired
24 child fields
idstringrequired
urlstringrequired
ig_handlestringrequired
shop_namestringrequired
kindstringrequired
channelenumrequired
cold_dmcomment_replycategory_pagein_personadasked_first
itemsarray of objectrequired
4 child fields
namestringrequired
price_pencenumber, nullablerequired
price_from_captionbooleanrequired
photo_idstring, nullablerequired
is_testbooleanrequired
statusenumrequired
draftsentopenedclaimedliveexpired
preview_typeenumrequired
name_onlywith_photos
expires_atstringrequired
expires_in_daysnumber, nullablerequired
created_atstringrequired
updated_atstringrequired
sent_atstring, nullablerequired
followed_up_atstring, nullablerequired
first_opened_atstring, nullablerequired
last_opened_atstring, nullablerequired
open_countnumberrequired
claimed_atstring, nullablerequired
claimed_store_idstring, nullablerequired
ownership_verified_atstring, nullablerequired
claim_undone_atstring, nullablerequired
photosarray of objectrequired
7 child fields
idstringrequired
roleenumrequired
logoproduct
sortnumberrequired
widthnumber, nullablerequired
heightnumber, nullablerequired
urlstring, nullablerequired
created_atstringrequired
curl -X POST "https://www.membber.com/api/v1/admin-previews/ce5f1b03-0000-4000-8000-d0c5000000ce/photos/confirm" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "path": "<path>",
    "role": "logo"
  }'
Response, 200
{
  "preview": {
    "id": "00000d1b-0000-4000-8000-d0c500000000",
    "url": "https://example.com/image.jpg",
    "ig_handle": "<ig_handle>",
    "shop_name": "<shop_name>",
    "kind": "<kind>",
    "channel": "cold_dm",
    "items": [
      {
        "name": "Example name",
        "price_pence": 1500,
        "price_from_caption": true,
        "photo_id": "b40c2e48-0000-4000-8000-d0c5000000b4"
      }
    ],
    "is_test": true,
    "status": "draft",
    "preview_type": "name_only",
    "expires_at": "<expires_at>",
    "expires_in_days": 1,
    "created_at": "<created_at>",
    "updated_at": "<updated_at>",
    "sent_at": "<sent_at>",
    "followed_up_at": "<followed_up_at>",
    "first_opened_at": "<first_opened_at>",
    "last_opened_at": "<last_opened_at>",
    "open_count": 1,
    "claimed_at": "<claimed_at>",
    "claimed_store_id": "6a0dc31d-0000-4000-8000-d0c50000006a",
    "ownership_verified_at": "<ownership_verified_at>",
    "claim_undone_at": "<claim_undone_at>",
    "photos": [
      {
        "id": "00000d1b-0000-4000-8000-d0c500000000",
        "role": "logo",
        "sort": 1,
        "width": 1,
        "height": 1,
        "url": "https://example.com/image.jpg",
        "created_at": "<created_at>"
      }
    ]
  }
}

Previews: the do-not-contact list.

Internal-admin. Newest first, 200 at most. Handle, source and date only.

Parameters

qstringqueryoptional

Handle search (contains).

Response, 200

entriesarray of objectrequired
3 child fields
ig_handlestringrequired
sourceenumrequired
not_for_mestop_replyadmin
added_atstringrequired
truncatedbooleanrequired
curl -G "https://www.membber.com/api/v1/admin-previews/do-not-contact" \
  -H "Authorization: Bearer $MEMBBER_TOKEN"
Response, 200
{
  "entries": [
    {
      "ig_handle": "<ig_handle>",
      "source": "not_for_me",
      "added_at": "<added_at>"
    }
  ],
  "truncated": true
}

Previews: never contact this handle again.

Internal-admin. Adds the handle (she replied STOP, or the founder decided). Any unclaimed preview for the handle is deleted with it, photos included. Idempotent: an existing entry keeps its first date.

Request body

ig_handlestringrequired
sourceenumrequired
stop_replyadmin

Response, 200

entryobjectrequired
3 child fields
ig_handlestringrequired
sourceenumrequired
not_for_mestop_replyadmin
added_atstringrequired
alreadybooleanrequired
deleted_preview_idstring, nullablerequired
curl -X POST "https://www.membber.com/api/v1/admin-previews/do-not-contact" \
  -H "Authorization: Bearer $MEMBBER_TOKEN" \
  -H "Idempotency-Key: 1f0e2d3c-4b5a-4678-9abc-def012345678" \
  -H "Content-Type: application/json" \
  -d '{
    "ig_handle": "<ig_handle>",
    "source": "stop_reply"
  }'
Response, 200
{
  "entry": {
    "ig_handle": "<ig_handle>",
    "source": "not_for_me",
    "added_at": "<added_at>"
  },
  "already": true,
  "deleted_preview_id": "eb13e4d8-0000-4000-8000-d0c5000000eb"
}
WhatsApp
Book a Call
Start Free