Twitter (X) Snowflake IDs: the 64-bit Layout and How to Decode One

By TwitterAPI.io Team•15 min read
Diagram of the 64-bit Twitter (X) Snowflake ID. From bit 63 to bit 0: one unused sign bit, a 41-bit timestamp in milliseconds since the Twitter epoch (id >> 22), 5 bits datacenter, 5 bits worker and a 12-bit sequence (id & 0xFFF). Worked example: post ID 298781148975104 by @ev shifted right by 22 is 71,234,977 ms; adding 1288834974657 gives 2010-11-04 21:30:09.634 UTC, the same second as the API createdAt, with datacenter 0, worker 1 and sequence 0. Footer: on 1,000 recent posts from 10 public accounts collected in 2026, 100% decode to the exact createdAt second.
The Snowflake bit layout from Twitter's archived snowflake-2010 source, with a real ID decoded step by step. The footer number comes from the study below.

This page explains the ID format itself: where the 64 bits go, why the epoch is 1288834974657, how to decode an ID in Python, JavaScript and SQL, and where the formula silently fails. If you only want the answer for one post, paste it into our free tweet ID to date tool at /tools/twitter-timestamp; if you need to turn a handle into its numeric user ID, use the ID finder at /tools/twitter-id-finder. Both are linked at the end. Our guide to the X-API-Key header and the Python guide cover authentication and requests; this page is only about what is inside the number.

Most explainers stop at the bit diagram and a one-line formula. We wanted to know whether the formula still holds for real data, so we pulled IDs and createdAt values straight from the API and compared them: 1,000 current posts from 10 public accounts, 170 posts from the weeks around the November 2010 switch, and the creation records of 1,072 accounts going back to 2006. The short version: for posts it is exact to the second, for user accounts it is not, and for anything older than November 2010 it is not a Snowflake at all.

Snowflake also became a pattern well beyond Twitter. Discord, Mastodon and many in-house systems use the same idea with a different epoch or bit split, and libraries such as @sapphire/snowflake on npm ship both a Twitter and a Discord decoder. The last section shows how the variants differ so you apply the right constant.

01 — Section

What a Twitter Snowflake ID is

Snowflake is the service Twitter wrote in 2010 to hand out unique IDs without a central counter. The original README in github.com/twitter-archive/snowflake (the snowflake-2010 tag) lists the requirements: at least 10,000 IDs per second per process, a response in about 2 ms, no coordination between machines, IDs that are roughly time ordered (k-sorted within about a second) and directly sortable, and a size under 64 bits. Generating IDs on many machines at once, with each machine stamping its own clock time and its own machine number, meets all of them.

The repository is no longer maintained. Its current README says Twitter retired the initial release, will not accept pull requests or answer issues for it, and that the source stays reachable from the snowflake-2010 tag; GitHub shows the repository as archived on September 18, 2021. The ID format did not retire with it. X's developer documentation (docs.x.com/fundamentals/x-ids) still says X IDs are 64-bit unsigned integers generated by a system called Snowflake, each encoding a timestamp, a worker number and a sequence number, and that every object in the API, posts, users, lists, DMs and Spaces, has one.

Why it matters to you. Because the creation time sits inside the ID, you can tell when a post was written from its URL alone, sort posts without fetching them, and turn a date into an ID boundary for search. Because the ID is wider than 53 bits, you can also corrupt it by accident in any language that stores numbers as 64-bit floats. Both sides are covered below.

02 — Section

The 64-bit layout, bit by bit

The archived IdWorker.scala builds every ID with one expression: ((timestamp - twepoch) << 22) | (datacenterId << 17) | (workerId << 12) | sequence, with twepoch = 1288834974657L, datacenterIdBits = 5, workerIdBits = 5 and sequenceBits = 12. Read from the most significant bit down, that gives:

BitsWidthFieldExtract with
631unused sign bit, always 0none
62 to 2241ms since 1288834974657id >> 22
21 to 175datacenter ID (0-31)(id >> 17) & 0x1F
16 to 125worker ID (0-31)(id >> 12) & 0x1F
11 to 012sequence (0-4095)id & 0xFFF

The epoch. 1288834974657 ms is Thursday, November 4, 2010, 01:42:54.657 UTC. It is not a round number because Twitter took the moment it set the constant, not a calendar boundary. The README says 41 bits of milliseconds with a custom epoch gives about 69 years, so the timestamp field runs out around 2080.

The machine bits. The README describes 10 bits of configured machine ID, up to 1,024 machines; the code splits them into 5 bits of datacenter and 5 bits of worker. X has never documented what its current datacenter and worker numbers mean, so treat them as opaque. In our 1,000 recent post IDs the datacenter field took only two values (11 and 13), and the worker field took 30 of its 32 possible values.

The sequence. Within one millisecond on one worker, the 12-bit counter numbers the IDs 0 to 4,095, then the generator waits for the next millisecond. That is why two IDs from the same worker in the same millisecond still differ and still sort in issue order.

Why IDs sort by time. The timestamp occupies the highest bits, so a larger ID almost always means a later post. Across machines the order is only as good as their clocks (the README promised about a second), which is why X calls them roughly time ordered, not strictly ordered.

03 — Section

Decode a tweet ID to a timestamp (Python, JavaScript)

The tweet ID is the number at the end of a post URL: in x.com/<user>/status/1234567890123456789 it is everything after status/. Decoding is two integer operations and needs no API call.

Python. Python integers are arbitrary precision, so (int(tweet_id) >> 22) + 1288834974657 is exact; divide by 1,000 and pass it to datetime.fromtimestamp(..., tz=timezone.utc). The complete script at the end of this page does that for a whole timeline and checks each result against createdAt.

JavaScript. Do not use Number. A 61-bit ID does not fit a double: when we pushed our 1,000 real IDs through a float64, 998 of them changed, by up to 128. The timestamp bits happened to survive in all 1,000 cases, but the ID itself is wrong, so any lookup with it fails. Use BigInt as in the snippet below, and when you read API JSON keep the ID as a string (twitterapi.io returns id as a string; X's v1.1 payloads carry id_str for the same reason).

Library option. @sapphire/snowflake (MIT, version 3.5.5 on npm, BigInt based) exports TwitterSnowflake and DiscordSnowflake with a deconstruct() method that returns the timestamp, worker, process and increment fields. It is a convenient choice when you already handle Discord IDs in the same codebase.

A worked example. Take post 298781148975104 by @ev, the first Snowflake-era post in our 2010 sample. 298781148975104 >> 22 is 71,234,977, the milliseconds after the epoch (about 19.79 hours). Adding 1288834974657 gives 1288906209634, which is 2010-11-04 21:30:09.634 UTC. The API reports createdAt as Thu Nov 04 21:30:09 +0000 2010: the same second, with the 634 ms that the string format drops. The low bits read datacenter 0, worker 1, sequence 0.

javascript
// Decode a Twitter (X) Snowflake ID in Node.js or the browser. Keep the ID a string.
const TWEPOCH = 1288834974657n;

function decodeSnowflake(idStr) {
  const id = BigInt(idStr);
  const ms = (id >> 22n) + TWEPOCH;
  return {
    createdAt: new Date(Number(ms)).toISOString(), // ms fits safely in a Number
    datacenter: Number((id >> 17n) & 0x1Fn),
    worker: Number((id >> 12n) & 0x1Fn),
    sequence: Number(id & 0xFFFn),
  };
}

function idFromUrl(url) {
  const m = url.match(/status(?:es)?\/(\d+)/);
  return m ? m[1] : null;
}

console.log(decodeSnowflake("298781148975104"));
// { createdAt: '2010-11-04T21:30:09.634Z', datacenter: 0, worker: 1, sequence: 0 }

// Wrong: Number("2112847277282721888") === 2112847277282721800, a different post.
04 — Section

We decoded 1,000 real tweet IDs: how exact is it?

We pulled the 100 most recent posts of each of 10 public accounts (@NASA, @github, @nvidia, @Xbox, @SpaceX, @NBA, @BBCWorld, @elonmusk, @jack and @Microsoft) through /twitter/user/last_tweets, decoded every id with Python integers and subtracted the createdAt timestamp the API returns for the same post.

CheckResult
Post IDs decoded1,000 from 10 accounts
Decoded second equals createdAt second1,000 of 1,000 (100%)
Decoded minus createdAt, msmin 3, median 518, p95 938, max 999
ID order agrees with time order999 of 999 neighbor pairs
ID sizeall 19 digits, 61 bits
Datacenter values seen2 (11 and 13)
Sequence fieldmedian 258, max 510

Reading the offsets. createdAt comes in the form Thu Nov 04 21:30:09 +0000 2010, with whole seconds only, so a correct decode must land between 0 and 999 ms after it. Every one did, and the offsets are spread evenly across that range (chart below), which is what you expect when the API simply truncates the milliseconds. There is no sign of a systematic shift between the clock that stamped the ID and the clock that produced createdAt.

What the sequence field shows. The 2010 code resets the sequence to 0 at each new millisecond, so at low load most IDs would end in a small number. Ours did not: only 0.1% had a sequence of 0 and the median was 258. Either X's current generator assigns the low bits differently from the 2010 release or load is high enough that the counter rarely starts fresh; X does not document which. For decoding it does not matter, because the timestamp is in the top bits.

Practical takeaway. For posts, the ID is a better timestamp than createdAt: it carries milliseconds, and you can read it from a URL without any request. Our free /tools/twitter-timestamp tool runs this exact decode for a batch of URLs or IDs and exports a CSV.

Bar chart of decoded Snowflake timestamp minus API createdAt for 1,000 post IDs, in ten 100 ms bins from 0-99 to 900-999 ms. Counts: 88, 109, 106, 93, 89, 84, 118, 117, 108, 88. Every ID falls between 3 and 999 ms, median 518 ms.
All 1,000 post IDs decode into the second the API reports; the ID keeps the milliseconds that createdAt drops. 100 recent posts each from 10 public accounts, collected in 2026.
05 — Section

User IDs: Snowflakes only since 2016, and they run early

User IDs are not all Snowflakes. Twitter kept handing out sequential user IDs long after posts switched, so any account old enough has an ID that is just a counter. We collected the creation records of 1,072 accounts that appeared as authors of Top search results, as followers and followings of @NASA, and in user search results, and checked each ID against its createdAt.

Accounts createdAccountsLegacy sequential IDSnowflake, same second
2006 to 2015322322 (100%)0
2016 to 201965452 of 61 Snowflakes
20202600
2021 onward65903 (0.5%)

The switch. The newest legacy user ID in our sample belongs to an account created in February 2016; it is 10 digits (33 bits). The oldest Snowflake user ID belongs to an account created in April 2016. So for user IDs the change happened in the first half of 2016. A legacy user ID shifted right by 22 gives a number of milliseconds so small that the decode lands within about a second of the 2010 epoch: obviously wrong for an account from 2009, and plausible-looking for one from late 2010.

The surprise. Snowflake user IDs from 2016 to 2019 behave like post IDs: 85.2% decode to the exact createdAt second. From 2020 on, almost none do. For the 659 accounts created in 2021 or later, the decoded time is a median of 47 seconds before createdAt, the 90th percentile is 174 seconds early, and not a single one decodes later than createdAt. That pattern is consistent with the ID being reserved at the start of sign-up and createdAt being written when sign-up completes, but X does not document its sign-up flow, so take that as our reading, not a fact.

Practical takeaway. For account age, read createdAt from /twitter/user/info (18 credits per profile, $0.18 per 1,000) instead of decoding the user ID. A decoded user ID is fine for a rough year, or for ordering accounts, but it can be off by minutes for current accounts and by years for legacy ones. Our /tools/twitter-account-age-checker reads the profile's creation date rather than decoding the ID, and /tools/twitter-id-finder converts a handle to its numeric ID if you need the ID itself.

Stacked bar chart of 1,072 accounts by creation year from 2007 to 2026. Grey legacy sequential IDs fill every year through 2015 and part of 2016. Blue Snowflake IDs that decode to the createdAt second dominate 2016 to 2019. Orange Snowflake IDs that decode before createdAt fill 2020 to 2026, with yearly medians between 17 and 74 seconds early.
User IDs: legacy through February 2016, Snowflakes from April 2016, and from 2020 on they decode before createdAt. 1,072 accounts collected in 2026; aggregates only.
06 — Section

Before November 2010: when the formula gives nonsense

Posts written before the switch carry the old sequential IDs, and the formula does not reject them, it quietly returns a time near the epoch. To find the exact boundary we searched the posts of @jack, @biz and @ev around the switch and pulled post 20, the first post on the service, by ID: 170 posts in total, 52 with legacy IDs and 118 with Snowflakes.

PostIDBitsNaive decodeReal createdAt
@jack, first post2052010-11-04 01:42:54Mar 21, 2006 20:50:14
@jack, last legacy seen29697952096352010-11-04 01:43:01Nov 4, 2010 20:20:45
@ev, first Snowflake seen298781148975104492010-11-04 21:30:09Nov 4, 2010 21:30:09

The boundary. In our sample the last legacy ID appeared at 20:20:45 UTC on November 4, 2010 and the first Snowflake 1.16 hours later, about 20 hours after the epoch constant itself. All 118 Snowflake-era posts in the sample decoded to their exact createdAt second. The ID jumped from 11 digits to 15 digits, and because the first Snowflakes were already far larger than the last legacy ID, sorting by ID still matched sorting by time across the switch for every post in our sample.

A safe guard. In our data every legacy post ID was 11 digits or fewer (the last one about 29.7 billion): treat such an ID as legacy and fetch createdAt instead of decoding it. In code, a threshold of 2**40 (about 1.1 trillion) works for both posts and users: every legacy ID in our data, post or user, was far below it (the largest legacy user ID had 33 bits) and every Snowflake far above it (the smallest had 49 bits).

If you work with old archives, the /twitter/tweets endpoint takes a comma-separated list in tweet_ids and returns createdAt for each post (15 credits per post returned), which is the reliable way to date pre-2010 posts.

07 — Section

Run it backward: timestamps to IDs, search windows and SQL

Because the layout is public, you can build an ID from a time: (ms - 1288834974657) << 22 is the smallest possible ID for that millisecond. That is useful in two places.

Exact search windows. The search endpoint accepts X's since_id: and max_id: operators. We built both bounds from midnight UTC timestamps one week apart and sent from:NASA since_id:<start> max_id:<end> to /twitter/tweet/advanced_search: 20 of 20 posts returned fell inside the window. since: and until: take calendar dates; ID bounds work to the millisecond, and they are a natural checkpoint: store the largest ID you have seen and pass it as since_id: on the next run.

Cursorless backfills. If a long backfill stops, you can restart it from the last ID you stored without keeping a cursor, because the ID encodes where you were in time.

SQL. Every major database can decode IDs stored as 64-bit integers (Snowflakes fit in a signed BIGINT because the top bit is 0). The snippet shows PostgreSQL, MySQL and BigQuery; store the column as BIGINT, or decode from text with a cast.

Cost of pulling the reference data. Decoding is free. If you also want createdAt from the API to check or enrich IDs, twitterapi.io bills tweet endpoints at 15 credits per post returned, $0.15 per 1,000 posts, and profiles at 18 credits each, $0.18 per 1,000. The official X API pay-per-usage rate card (docs.x.com/x-api/getting-started/pricing) lists $0.005 per post read and $0.010 per user read, which is $5 per 1,000 posts, about 33 times more per 1,000 posts. No X account is needed for reads; see /pricing for plans.

sql
-- PostgreSQL: id BIGINT
SELECT id,
       to_timestamp(((id >> 22) + 1288834974657) / 1000.0) AT TIME ZONE 'UTC' AS created_utc
FROM tweets;

-- MySQL: id BIGINT UNSIGNED
SELECT id,
       FROM_UNIXTIME(((id >> 22) + 1288834974657) / 1000) AS created_utc
FROM tweets;

-- BigQuery: id INT64 (or SAFE_CAST(id_str AS INT64))
SELECT id,
       TIMESTAMP_MILLIS((id >> 22) + 1288834974657) AS created_utc
FROM dataset.tweets;

-- Timestamp to the smallest ID for that moment (PostgreSQL)
SELECT ((EXTRACT(EPOCH FROM now() - INTERVAL '7 days') * 1000)::BIGINT
        - 1288834974657) << 22 AS since_id_7_days_ago;
08 — Section

Discord, Mastodon and other Snowflake variants

Snowflake is now a family. The idea is always the same, a millisecond timestamp in the high bits and machine plus counter bits below, but the epoch and the field split change, and using the wrong epoch shifts every date by years.

SystemEpochTimestamp bitsDecode
Twitter / X1288834974657 (Nov 4, 2010)41, shifted 22(id >> 22) + 1288834974657
Discord1420070400000 (Jan 1, 2015)42, shifted 22(id >> 22) + 1420070400000
Mastodonvariant, not documented as stablen/atreat as opaque string

Discord. Discord's developer reference documents a timestamp in bits 63 to 22 counted from the first second of 2015, then a 5-bit internal worker ID, a 5-bit internal process ID and a 12-bit increment. The shift is the same as Twitter's; only the epoch differs. Discord's table counts the timestamp as 42 bits because it includes the top bit in the field.

Mastodon. Mastodon's API guidelines say IDs are generated with a variant of Snowflake but must always be treated as opaque strings, never cast to integers, and that other servers may not use numbers at all. Sort them by length, then lexically, if you need to.

Your own system. If you generate IDs yourself, the 2010 Twitter source is still a clear reference for the pattern: pick an epoch close to your launch to extend the 69-year range, assign worker IDs from configuration, and wait for the next millisecond when the 12-bit counter overflows. Copy the pattern, not Twitter's epoch.

09 — Section

How we collected this

Question. Does (id >> 22) + 1288834974657 reproduce the createdAt the API returns, for posts and for user accounts, and where does it stop applying?

Posts. The 100 most recent posts of each of 10 public organization and public-figure accounts (@NASA, @github, @nvidia, @Xbox, @SpaceX, @NBA, @BBCWorld, @elonmusk, @jack, @Microsoft) via /twitter/user/last_tweets, 1,000 posts, collected in 2026.

The 2010 switch. 170 posts by @jack, @biz and @ev from the weeks around November 2010 via /twitter/tweet/advanced_search with since:/until: dates, plus post 20 via /twitter/tweets.

Users. 1,072 distinct accounts: authors of Top results for neutral topic searches, recent followers and followings of @NASA, and user search results. These are mostly private individuals, so we keep only aggregates (creation year, ID size, offset bucket); no handle, ID or text is published.

Since-ID check. One /twitter/tweet/advanced_search call for @NASA with since_id:/max_id: bounds built from timestamps a week apart.

Size and cost. 91 requests in total; about 1,550 posts returned, about $0.23 at $0.15 per 1,000, plus a few cents of follower and user-search reads.

What the sample cannot show. The user sample is skewed toward new accounts (a large share are recent @NASA followers) and has few accounts from 2015 to 2019, so the exact month of the user-ID switch and the year the early offset began are bounded, not pinned. We cannot see X's internal ID service, so the meaning of the datacenter and worker values, and the reason user IDs run early, are interpretations.

Reproduce it. The analysis and chart scripts, the protocol and the results are in the study folder data/studies/twitter-snowflake/ of this site's repository; raw pages are committed only for the public accounts.

python
"""Decode Twitter (X) Snowflake IDs and check them against createdAt.

pip install requests
export TWITTERAPI_IO_KEY=...   # from https://twitterapi.io/dashboard
"""
import os
from datetime import datetime, timezone

import requests

BASE = "https://api.twitterapi.io"
HEADERS = {"X-API-Key": os.environ["TWITTERAPI_IO_KEY"]}
TWEPOCH = 1288834974657  # ms, 2010-11-04 01:42:54.657 UTC


def decode(snowflake_id):
    i = int(snowflake_id)  # Python ints are exact; never float()
    if i < 2 ** 40:
        raise ValueError("legacy pre-Snowflake ID, fetch createdAt instead")
    ms = (i >> 22) + TWEPOCH
    return {
        "utc": datetime.fromtimestamp(ms / 1000, tz=timezone.utc),
        "ms": ms,
        "datacenter": (i >> 17) & 0x1F,
        "worker": (i >> 12) & 0x1F,
        "sequence": i & 0xFFF,
    }


def id_for_time(dt):
    """Smallest possible Snowflake for a moment: use as since_id / max_id."""
    return (int(dt.timestamp() * 1000) - TWEPOCH) << 22


def last_tweets(user, pages=2):
    cursor = ""
    for _ in range(pages):
        r = requests.get(f"{BASE}/twitter/user/last_tweets",
                         headers=HEADERS,
                         params={"userName": user, "cursor": cursor},
                         timeout=30)
        r.raise_for_status()
        body = r.json()
        for t in body.get("data", {}).get("tweets", []):
            yield t
        if not body.get("has_next_page"):
            break
        cursor = body.get("next_cursor", "")


def check(user):
    rows = []
    for t in last_tweets(user):
        d = decode(t["id"])
        api = datetime.strptime(t["createdAt"], "%a %b %d %H:%M:%S %z %Y")
        offset_ms = d["ms"] - int(api.timestamp()) * 1000
        rows.append(offset_ms)
        print(t["id"], d["utc"].isoformat(timespec="milliseconds"),
              t["createdAt"], f"{offset_ms} ms")
    same = sum(0 <= o < 1000 for o in rows)
    print(f"{same}/{len(rows)} IDs decode to the createdAt second")


def search_window(user, start, end):
    """Posts between two datetimes, bounded by Snowflake IDs."""
    q = f"from:{user} since_id:{id_for_time(start)} max_id:{id_for_time(end)}"
    r = requests.get(f"{BASE}/twitter/tweet/advanced_search",
                     headers=HEADERS,
                     params={"query": q, "queryType": "Latest"},
                     timeout=30)
    r.raise_for_status()
    body = r.json()
    return body.get("tweets", []), body.get("has_next_page"), body.get("next_cursor")


if __name__ == "__main__":
    check("NASA")  # 2 pages = up to 40 posts = about $0.006
    week_end = datetime.now(timezone.utc)
    week_start = datetime.fromtimestamp(week_end.timestamp() - 7 * 86400, tz=timezone.utc)
    tweets, more, _ = search_window("NASA", week_start, week_end)
    print(len(tweets), "posts in the last 7 days (first page), more:", more)
10 — Questions

Questions readers ask

What is a Twitter Snowflake ID?

It is the 64-bit unique ID X (Twitter) assigns to posts, users, lists, DMs and Spaces. It packs a 41-bit millisecond timestamp since 1288834974657 (November 4, 2010), 5 bits of datacenter, 5 bits of worker and a 12-bit sequence, so IDs are unique without a central counter and sort roughly by creation time.

How do I convert a tweet ID to a date?

Shift the ID right by 22 bits and add 1288834974657: the result is the creation time in Unix milliseconds (UTC). In Python: datetime.fromtimestamp(((int(i) >> 22) + 1288834974657) / 1000, tz=timezone.utc). Or paste the ID or URL into our free /tools/twitter-timestamp tool. In our test on 1,000 real IDs the result always matched the API createdAt to the second.

What is the Twitter epoch 1288834974657?

It is the twepoch constant in Twitter's archived snowflake source (IdWorker.scala), in milliseconds since the Unix epoch. It corresponds to November 4, 2010, 01:42:54.657 UTC. Discord uses a different epoch, 1420070400000 (January 1, 2015), so never mix the two.

Can I get an account's creation date from its user ID?

Only roughly. Accounts created before 2016 have legacy sequential IDs that do not decode at all, and in our sample accounts created from 2021 on decode a median of 47 seconds before their real createdAt. Read createdAt from the profile instead, for example with /twitter/user/info or our account age checker.

Why does my tweet ID change in JavaScript?

Snowflake IDs need 61 bits and a JavaScript Number holds integers exactly only up to 53 bits, so parsing an ID as a number rounds it. In our test 998 of 1,000 IDs changed. Keep IDs as strings and use BigInt for bit operations; X's v1.1 API added id_str for this reason.

Do older tweets have Snowflake IDs?

No. Posts before November 4, 2010 have sequential IDs of up to 11 digits, such as 20 for the first post in 2006. Run through the formula they decode to a moment near the 2010 epoch. Treat any ID under 2 to the power of 40 as legacy and fetch createdAt for it.

Are Twitter IDs strictly in time order?

Roughly. The timestamp sits in the highest bits, so a larger ID nearly always means a later post, and in our sample ID order matched time order for every neighbor pair. Across machines the order depends on clock sync, which the original design promised to about one second, so do not rely on it for sub-second ordering between different posts.

Is Twitter's snowflake code still maintained?

No. The twitter-archive/snowflake repository says the initial release is retired, accepts no pull requests or issues, and keeps the source under the snowflake-2010 tag; GitHub shows it archived since September 18, 2021. The ID format itself is still documented by X and still used in every API response.

11 — Further reading

Continue

Sources & further reading
More from this series
Build it

Stop reading. Start building.

Starter credits cover real testing on real data. Google sign-in, no card, no application queue.

Get an API key