{"id":"c1cc9bf575ef0e0c","slug":"api-keys","trashed":false,"description":"","likes":42,"publish_level":"live_unlisted","forks":1,"fork_of":null,"has_importers":false,"update_time":"2023-09-19T23:34:51.901Z","first_public_version":175,"paused_version":null,"publish_time":"2023-11-07T20:00:36.135Z","publish_version":196,"latest_version":196,"thumbnail":"a621f2ac8378853e060b407f9a874aa821c32908317ec92ec8f9472aebcab95f","default_thumbnail":"5409d6c6c5635a7d2901506b28eb36b454d32555393757b49b4c06960e42f57d","roles":[],"sharing":null,"edits":[{"node_id":188,"value":"Another option to embed a notebook is by creating an API key. To create a new API key, visit the [API Keys section](/settings/api-keys) in your personal or team settings and click on **New API key**. Give it a friendly description so that you can remember what it’s being used for later."}],"owner":{"id":"f35c755083683fe5","avatar_url":"https://avatars.observableusercontent.com/avatar/5a51c3b908225a581d20577e488e2aba8cbc9541c52982c638638c370c3e5e8e","login":"observablehq","name":"Observable","bio":"The end-to-end solution for building and hosting better data apps, dashboards, and reports.","home_url":"https://observablehq.com","type":"team","tier":"enterprise_2024"},"creator":{"id":"783616ba9fb55f5d","avatar_url":"https://avatars.observableusercontent.com/avatar/fa1903f8171d4621ef49de28e0ff1fb965960ec87df175d8b543c4b09508b45b","login":"jashkenas","name":"Jeremy Ashkenas","bio":"Used to work on @observablehq — still think it rocks.\n🏍 🌎 👶","home_url":"http://ashkenas.com","tier":"public"},"authors":[],"collections":[{"id":"f32cb7b0d22ffb6a","type":"public","slug":"editing-publishing-collaborating","title":"Sharing and Collaboration","description":"Workflows for creating content on Observable & sharing it with the world.","update_time":"2022-12-12T19:07:32.583Z","pinned":false,"ordered":true,"custom_thumbnail":null,"default_thumbnail":"de9161c34e50d0828712364a37f169441f25e3f9bc0d360e1cc685e21b1ed912","thumbnail":"de9161c34e50d0828712364a37f169441f25e3f9bc0d360e1cc685e21b1ed912","listing_count":1,"parent_collection_count":1,"owner":{"id":"f35c755083683fe5","avatar_url":"https://avatars.observableusercontent.com/avatar/5a51c3b908225a581d20577e488e2aba8cbc9541c52982c638638c370c3e5e8e","login":"observablehq","name":"Observable","bio":"The end-to-end solution for building and hosting better data apps, dashboards, and reports.","home_url":"https://observablehq.com","type":"team","tier":"enterprise_2024"}}],"files":[{"id":"e2233147970af02d87711a45f6e4dd2088b8b5b14b345403d851c7adec69a8bf00e671301b10be97d7a0e7360432d277ea595895e538a8743ac7578890103d62","url":"https://static.observableusercontent.com/files/e2233147970af02d87711a45f6e4dd2088b8b5b14b345403d851c7adec69a8bf00e671301b10be97d7a0e7360432d277ea595895e538a8743ac7578890103d62","download_url":"https://static.observableusercontent.com/files/e2233147970af02d87711a45f6e4dd2088b8b5b14b345403d851c7adec69a8bf00e671301b10be97d7a0e7360432d277ea595895e538a8743ac7578890103d62?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27image.png","name":"image.png","create_time":"2019-12-05T21:01:15.925Z","mime_type":"image/png","status":"public","size":150356,"content_encoding":null,"private_bucket_id":null},{"id":"16fa5e5881f01ab71c3399fe756a7792f75b8a7a9dfd5d16f2032ec14850237900787b26e092addfb6f14f160992a8f62dec3ac61bedf2fc5627d966d29fc9cf","url":"https://static.observableusercontent.com/files/16fa5e5881f01ab71c3399fe756a7792f75b8a7a9dfd5d16f2032ec14850237900787b26e092addfb6f14f160992a8f62dec3ac61bedf2fc5627d966d29fc9cf","download_url":"https://static.observableusercontent.com/files/16fa5e5881f01ab71c3399fe756a7792f75b8a7a9dfd5d16f2032ec14850237900787b26e092addfb6f14f160992a8f62dec3ac61bedf2fc5627d966d29fc9cf?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27image%25402.png","name":"image@2.png","create_time":"2019-12-05T21:10:51.312Z","mime_type":"image/png","status":"public","size":240584,"content_encoding":null,"private_bucket_id":null},{"id":"3ddd8109c4f65234d427292ef46c26552d6e809eb7dfde9aab3c8dca62244eacc9b3674d4596cd1ec66f2e5cbc9d01a1f006a9fc750812d80790ff4ec8ecef47","url":"https://static.observableusercontent.com/files/3ddd8109c4f65234d427292ef46c26552d6e809eb7dfde9aab3c8dca62244eacc9b3674d4596cd1ec66f2e5cbc9d01a1f006a9fc750812d80790ff4ec8ecef47","download_url":"https://static.observableusercontent.com/files/3ddd8109c4f65234d427292ef46c26552d6e809eb7dfde9aab3c8dca62244eacc9b3674d4596cd1ec66f2e5cbc9d01a1f006a9fc750812d80790ff4ec8ecef47?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27image%25404.png","name":"image@4.png","create_time":"2019-12-05T23:45:13.335Z","mime_type":"image/png","status":"public","size":416607,"content_encoding":null,"private_bucket_id":null},{"id":"e9ec68334a14910178f365d3fdd29da1b9e545b680a60cf213acc2334ab92541d4ccdebe2ca4c6043b4efa218e33132f92ed703c90c09a82b91ebd89404cc3aa","url":"https://static.observableusercontent.com/files/e9ec68334a14910178f365d3fdd29da1b9e545b680a60cf213acc2334ab92541d4ccdebe2ca4c6043b4efa218e33132f92ed703c90c09a82b91ebd89404cc3aa","download_url":"https://static.observableusercontent.com/files/e9ec68334a14910178f365d3fdd29da1b9e545b680a60cf213acc2334ab92541d4ccdebe2ca4c6043b4efa218e33132f92ed703c90c09a82b91ebd89404cc3aa?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27image%25405.png","name":"image@5.png","create_time":"2019-12-05T23:57:59.135Z","mime_type":"image/png","status":"public","size":21923,"content_encoding":null,"private_bucket_id":null},{"id":"aa9bb99a4804e9d147b63787d2ddc0ea46b859776e6dcf437443d0ba586d2fe849501a2857c7d180a13b0d5412e33b499f03858bfaa8197397e7cf4dfc73c803","url":"https://static.observableusercontent.com/files/aa9bb99a4804e9d147b63787d2ddc0ea46b859776e6dcf437443d0ba586d2fe849501a2857c7d180a13b0d5412e33b499f03858bfaa8197397e7cf4dfc73c803","download_url":"https://static.observableusercontent.com/files/aa9bb99a4804e9d147b63787d2ddc0ea46b859776e6dcf437443d0ba586d2fe849501a2857c7d180a13b0d5412e33b499f03858bfaa8197397e7cf4dfc73c803?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27embedModal%25401.png","name":"embedModal@1.png","create_time":"2023-05-02T16:04:34.816Z","mime_type":"image/png","status":"public","size":200696,"content_encoding":null,"private_bucket_id":null},{"id":"7add36f8426db202603398511dd6df142ceb922b6bb6b850bc2531b3f1085aa515c17d043da91e706754a5842a8186535781de5264f60fd37b13429108c61f7a","url":"https://static.observableusercontent.com/files/7add36f8426db202603398511dd6df142ceb922b6bb6b850bc2531b3f1085aa515c17d043da91e706754a5842a8186535781de5264f60fd37b13429108c61f7a","download_url":"https://static.observableusercontent.com/files/7add36f8426db202603398511dd6df142ceb922b6bb6b850bc2531b3f1085aa515c17d043da91e706754a5842a8186535781de5264f60fd37b13429108c61f7a?response-content-disposition=attachment%3Bfilename*%3DUTF-8%27%27notebookKeys.png","name":"notebookKeys.png","create_time":"2023-05-02T16:04:34.816Z","mime_type":"image/png","status":"public","size":136191,"content_encoding":null,"private_bucket_id":null}],"comments":[{"id":"9802fa1059ff2dc2","content":"👋🏼 I think it would be nice to include something here about personal vs team API Keys! I just spent a long time debugging a problem, where I couldn't download a notebook from my team with an API Key. Turns out that team notebooks needed to be \"team shared\" in order for me to use a \"team API Key\" to download it, but since it wasnt mentioned here I didnt think to check it","node_id":26,"create_time":"2021-05-08T00:13:31.305Z","update_time":null,"resolved":true,"user":{"id":"113fc3dc69e1f893","avatar_url":"https://avatars.observableusercontent.com/avatar/fa4015f63c3a56af76b90247b0b0f8a98019b671f135157d746d3924eda27c07","login":"asg017","name":"Alex Garcia","bio":"Software engineer, available for freelance work! • he/him/his","home_url":"https://alexgarcia.xyz","tier":"pro"}},{"id":"a9ca047ea73876bd","content":"Hi, Alex, we added a note a few cells down about notebooks needing to be shared with the whole team for the API key to have access. Hope this addresses your suggestion.","node_id":26,"create_time":"2022-02-09T18:43:36.143Z","update_time":null,"resolved":true,"user":{"id":"e32d6575f6e25235","avatar_url":"https://avatars.observableusercontent.com/avatar/d1b0236c0308413347626db6ebcfcddf7584a1e67d1e99546fdcc01e7fd19549","login":"justinting","name":"Justin Ting","bio":"","home_url":"","tier":"pro"}},{"id":"14c0dda86b429661","content":"I wonder, what are the available options for the FORMAT field? It would be great to list those here.","node_id":26,"create_time":"2022-02-28T18:55:10.060Z","update_time":null,"resolved":true,"user":{"id":"6a6e2fdbba1803f2","avatar_url":"https://avatars.observableusercontent.com/avatar/27282ae25b74721def112d68db7d4c2dfd43d48f6b2f232e34cbbdb2bedc9dc9","login":"curran","name":"Curran Kelleher","bio":"Fascinated by visual presentation of data as a means to understand the world better and communicate that understanding to others.","home_url":"https://vizhub.com","tier":"public"}},{"id":"78ca1f4f6f443348","content":"Is there a way to get the latest version, rather than specifying a particular version? If we must specify a version, is there a way to find out what that version is? Thanks!","node_id":26,"create_time":"2022-02-28T19:06:37.942Z","update_time":null,"resolved":true,"user":{"id":"6a6e2fdbba1803f2","avatar_url":"https://avatars.observableusercontent.com/avatar/27282ae25b74721def112d68db7d4c2dfd43d48f6b2f232e34cbbdb2bedc9dc9","login":"curran","name":"Curran Kelleher","bio":"Fascinated by visual presentation of data as a means to understand the world better and communicate that understanding to others.","home_url":"https://vizhub.com","tier":"public"}},{"id":"eeae85aa6f7dd28e","content":"Oh hey! It turns out that you can omit the version and the latest is fetched. Wonderful!","node_id":26,"create_time":"2022-02-28T19:36:17.953Z","update_time":null,"resolved":true,"user":{"id":"6a6e2fdbba1803f2","avatar_url":"https://avatars.observableusercontent.com/avatar/27282ae25b74721def112d68db7d4c2dfd43d48f6b2f232e34cbbdb2bedc9dc9","login":"curran","name":"Curran Kelleher","bio":"Fascinated by visual presentation of data as a means to understand the world better and communicate that understanding to others.","home_url":"https://vizhub.com","tier":"public"}},{"id":"1ebad68c4242ffe4","content":"The supported formats are “js” and “tgz”.","node_id":26,"create_time":"2022-02-28T19:59:36.348Z","update_time":null,"resolved":true,"user":{"id":"074c414ad1d825f5","avatar_url":"https://avatars.observableusercontent.com/avatar/82811927da99f8938001b2ef1f552ad2c47083e46ebc55a3a146a5a5848c4519","login":"mbostock","name":"Mike Bostock","bio":"Visualization toolmaker. Founder @observablehq. Creator @d3. Former @nytgraphics. Pronounced BOSS-tock.","home_url":"https://bost.ocks.org/mike/","tier":"pro"}},{"id":"da50a3ea3b4c5f2d","content":"Added note explicitly mentioning supported formats.","node_id":26,"create_time":"2022-02-28T20:50:58.665Z","update_time":null,"resolved":true,"user":{"id":"e32d6575f6e25235","avatar_url":"https://avatars.observableusercontent.com/avatar/d1b0236c0308413347626db6ebcfcddf7584a1e67d1e99546fdcc01e7fd19549","login":"justinting","name":"Justin Ting","bio":"","home_url":"","tier":"pro"}},{"id":"8e520bf1dc5c57ae","content":"Hello! I'm trying to use the API key to embed private notebooks but it's returning \"Not found.\" . What I tried doing is copying the same embed URL (as in the export option in the notebook) and adding to the link an additional argument for the API key: \nhttps://observablehq.com/embed/[notebook]?cells=[cell]&api_key=xxxx.\n\nAm I doing it wrong? What link should we use for embedding cells with the API?","node_id":26,"create_time":"2022-05-20T22:13:36.798Z","update_time":null,"resolved":true,"user":{"id":"fb5cec9bce9de2a5","avatar_url":"https://avatars.observableusercontent.com/avatar/3cbffbb44ef9da6ba4081171fbf36fac09a2a4a9712145351e9f14ead9b726d9","login":"awildtostes","name":"Lucas Tostes","bio":"","home_url":"","tier":"public"}},{"id":"0cbce9806f578c00","content":"Lucas, it looks like you are trying to embed a private notebook (with the API key) using the iframe embed method. Unfortunately that is not supported. The API key is only supported when you embed with JavaScript or React (the other options on the embed modal). \nWe clarified that on the embed modal also.","node_id":26,"create_time":"2022-10-11T15:36:55.212Z","update_time":null,"resolved":true,"user":{"id":"c1daf2951ad616fb","avatar_url":"https://avatars.observableusercontent.com/avatar/4a17a065d7a0f5f9a64a852f7b26a4f875c2ff69eb17264c3bd9f81e69285c05","login":"cobus","name":"Cobus Theunissen","bio":"","home_url":"","tier":"pro"}},{"id":"a85bd2e74a8da130","content":"I was under the impression that it would be possible to embed it using the iframe method too, but it's clear to me now.\nThank you very much, Cobus!","node_id":26,"create_time":"2022-10-11T16:34:21.743Z","update_time":null,"resolved":true,"user":{"id":"fb5cec9bce9de2a5","avatar_url":"https://avatars.observableusercontent.com/avatar/3cbffbb44ef9da6ba4081171fbf36fac09a2a4a9712145351e9f14ead9b726d9","login":"awildtostes","name":"Lucas Tostes","bio":"","home_url":"","tier":"public"}}],"commenting_lock":null,"suggestion_from":null,"suggestions_to":[],"version":196,"title":"API and notebook keys","license":null,"copyright":"","nodes":[{"id":0,"value":"# API and notebook keys\n\nObservable API keys allow you to [download and embed](/@observablehq/embeds?collection=@observablehq/embedding-notebooks) your private notebooks, securely. For example, you can use these keys to embed a visualization from a private notebook into your internal dashboard connected to private data from your intranet, or download a tarball of your private notebook and bundle it into an app.","pinned":false,"mode":"md","data":{},"name":""},{"id":193,"value":"Similar to API keys, when embedding a notebook you can create a **notebook key** that has a more limited scope of access to a particular notebook at a particular version. These keys also have access to referenced _database connections_ and _secrets_ in Iframe embeds.","pinned":false,"mode":"md","data":null,"name":""},{"id":192,"value":"### Creating notebook keys\n\nTo create a new notebook key, open the embed modal within a private notebook.\n\nIn the preview pane, you can configure the following options:\n\n- **Only this version**: Allows you to make the notebook key work only with the current version of the notebook. Only notebook referenced secrets and database connections will be available to the embed.\n- **Expiration**: Allows you to specify an expiration date for this key. (Can be _never_.) Note: This expiration date is displayed in your user's notebook key list in settings.\n\nAfter selection options, click \"Create notebook key\" to create a key with a generated name, which will be added to the embed code on the left.","pinned":false,"mode":"md","data":null,"name":""},{"id":191,"value":"<figure>\n  <img\n    style=\"border-radius:2px;box-shadow:0 4px 12px rgba(0,0,0,0.15), 0 0 0 1px rgba(0, 0, 0, 0.1);margin-left:27px;margin-bottom:40px;max-width: 650px\"\n    src=${await FileAttachment(\"embedModal@1.png\").url()}\n  />\n <figcaption>The <b>Preview</b> section includes a form to create a notebook key. Optionally pin to this notebook version, and provide an expiration date for the notebook key.</figcaption>\n</figure>","pinned":false,"mode":"html","data":null,"name":""},{"id":190,"value":"_Note: Once you create a notebook key, you cannot view the key again when re-opening the notebook. Create a new key if needed._","pinned":false,"mode":"md","data":null,"name":""},{"id":189,"value":"### Creating API keys","pinned":false,"mode":"md","data":null,"name":""},{"id":188,"value":"Another option to embed a notebook is by creating an API key. To create a new API key, visit the [API Keys section](/settings/api-keys) in your personal or team settings and click on **New API key**. Give it a friendly description so that you can remember what it’s being used for later.","pinned":false,"mode":"md","data":null,"name":""},{"id":8,"value":"html`<figure>\n  <img src=\"${await FileAttachment(\"image.png\").url()}\" style=\"border: 1px solid #eee; border-radius: 4px;\">\n</figure>`","pinned":false,"mode":"js","data":null,"name":null},{"id":22,"value":"Copy your key and keep it somewhere safe. ***Treat your API keys like passwords.*** API keys can be used to read any private notebook owned by the corresponding Observable account. Personal API keys can only read your personal notebooks, and team API keys can only read notebooks belonging to that team.\n\nThese keys are intended for loading private notebooks in private. ***Do not embed them in public web pages.*** If someone steals your API key, they can potentially use it to read any of your private notebooks until you delete it.","pinned":false,"mode":"md","data":{},"name":""},{"id":26,"value":"md`### Using API Keys\n\nTo use the key to request the \\`.js\\` or \\`.tgz\\` compiled version of a private notebook, you have two options: include it as an \\`api_key=xxxx\\` query parameter in the URL; or, include it as an HTTP header \\`Authorization: ApiKey xxxx\\`.\n\nThe URL format for retrieving a private notebook from the Observable API is:\n\n\\`\\`\\`\nhttps://api.observablehq.com/d/[NOTEBOOK_ID][@VERSION].[FORMAT]?v=3&api_key=xxxx\n\\`\\`\\`\n`","pinned":false,"mode":"js","data":null,"name":null},{"id":147,"value":"formatsNote = note(htl.html`<b>Note</b>: The two supported formats are .js or .tgz.`)","pinned":false,"mode":"js","data":null,"name":null},{"id":142,"value":"For example, this notebook’s current version JavaScript URL is:\n\n```\nhttps://api.observablehq.com/d/c1cc9bf575ef0e0c@128.js?v=3&api_key=xxxx\n```\n\nTo authenticate a request for a compiled private notebook with the API key as a URL query parameter looks like the following:","pinned":false,"mode":"md","data":{},"name":""},{"id":34,"value":"html`<figure>\n  <img src=${await FileAttachment(\"image@4.png\").url()}>\n</figure>`","pinned":false,"mode":"js","data":null,"name":null},{"id":39,"value":"Or on the command line, as an HTTP header:","pinned":false,"mode":"md","data":{},"name":""},{"id":42,"value":"html`<figure>\n  <img src=${await FileAttachment(\"image@2.png\").url()}>\n</figure>`","pinned":false,"mode":"js","data":null,"name":null},{"id":60,"value":"md`We recommend only using the \\`api_key=xxxx\\` query parameter for testing and development. For production, it’s safer to use the HTTP header to authenticate your requests.`","pinned":false,"mode":"js","data":null,"name":null},{"id":167,"value":"privateTeamsNote = note(htl.html`<b>Note</b>: For private Teams notebooks, the notebook has to be shared with the whole team for the API key to have access.`)","pinned":false,"mode":"js","data":null,"name":null},{"id":184,"value":"### Managing notebook & API keys\n\nIn the **API / Notebook keys** settings page, you can view and delete notebook keys.\n\n#### Notebook keys\n\nIn Notebook keys tab, you can view and manage all notebook keys for all notebooks for your account.\n\nNote that a single notebook can have multiple notebook keys. Keys can be pinned a version (i.e. `@12`), or can be unpinned and support embedding for future versions (`@12...`).\n\nAdditionally, Notebook keys can optionally expire if you set an expiration date.","pinned":false,"mode":"md","data":{},"name":""},{"id":183,"value":"html`<figure>\n  <img src=\"${await FileAttachment(\"notebookKeys.png\").url()}\">\n</figure>`","pinned":false,"mode":"js","data":null,"name":null},{"id":56,"value":"md`#### API keys\n\nAPI keys don’t expire, but you can delete them to immediately cause requests that use that key to fail. Feel free to rotate them regularly, or create different keys for different use cases within your team.\n\nIn the **API Keys** settings page, the last time the key was used to make a request is shown, so you can safely delete old or unused keys.`","pinned":false,"mode":"js","data":null,"name":null},{"id":68,"value":"html`<figure>\n  <img src=\"${await FileAttachment(\"image@5.png\").url()}\">\n</figure>`","pinned":false,"mode":"js","data":null,"name":null},{"id":181,"value":"## Key feature differences\n\nThis table provides a quick summary of the key differences between notebook keys and API keys:\n\n| Feature              | Notebook Key | API Key   |\n|----------------------|--------------|-----------|\n| Embed Private Notebooks | ✅ | ✅ |\n| Version Pinning | ✅ | ❌ |\n| Database connections | ✅ (iFrame only)   | ❌         |\n| Secrets              | ✅ (iFrame only)   | ❌         |\n| Expiration           | ✅ (optional) | ❌ (never expires) |","pinned":false,"mode":"md","data":null,"name":""},{"id":132,"value":"### Limitations\n\nNotebook keys grant access to a private notebook’s [secrets](https://observablehq.com/@observablehq/secrets) or [database clients](https://observablehq.com/@observablehq/connecting-to-databases) at the specified notebook version. API keys do not grant access, so it is recommended to use notebook keys to easily and securely embed notebooks.","pinned":false,"mode":"md","data":{},"name":""},{"id":179,"value":"---","pinned":false,"mode":"md","data":null,"name":""},{"id":151,"value":"note = ((contents) => htl.html`\n<div style=${{border: \"1px solid rgba(0, 0, 0, 0.05)\", padding: \"0.8rem\", fontFamily: \"var(--sans-serif)\", fontSize: \"smaller\", maxWidth: \"640px\", borderRadius: \"4px\", font: \"13px/1.5em var(--sans-serif)\", color: \"#444\", boxSizing: \"border-box\", background: \"hsl(55deg 80% 98%)\"}}>\n  ${contents}\n</div>\n`)","pinned":false,"mode":"js","data":null,"name":null}],"resolutions":[],"schedule":null,"last_view_time":null}