---
name: google-slides-oauth-app
description: >-
  The Google Slides API layer on top of the shared
  `google-cloud-console-oauth` skill — the two `presentations` scopes and why
  they are only sensitive, the Drive scope that decides the project's tier
  (the Slides API cannot list, search, copy, move or export a presentation),
  per-slide thumbnails and their 30-minute URLs, caller-supplied object IDs
  and fragile index arithmetic across `batchUpdate` calls, the "expensive
  read" quota bucket, and what the API does not do. Use when asked to get
  Google Slides OAuth credentials, scope a Slides integration, decide whether
  reading or generating decks needs a whole-Drive scope, or explain why a
  Slides connection cannot find, export or image a user's presentations. Read
  `google-cloud-console-oauth` first for the console mechanics, and
  `google-drive-oauth-app` whenever a Drive scope is in play; use the relevant
  product skill for other Google products.
---

# Google Slides OAuth2 App Registration

The Slides scopes are the cheap half of this job. `presentations` and `presentations.readonly` are **Sensitive** on
Google's own Slides scope page — there is no restricted Slides scope, so an app that holds nothing else pays only
what the base skill's §5 charges a sensitive-tier app, and none of what it charges a restricted one.

What makes a Slides integration expensive is the scope beside them. **The Slides API addresses a presentation by
`presentationId` and exposes no method that lists, searches, copies, moves, exports or watches one.** Enumerating a
customer's decks, rendering one to PPTX or PDF, dropping a generated deck into a folder, reading its comment threads —
every one of those is a Drive call. Which Drive scope you pair with `presentations` is therefore the decision that
sets the project's tier, and it is a product decision, not a console setting.

That fork is §2, and it is the point of this file. Settle it before anyone touches Data Access.

## Built on: `google-cloud-console-oauth`

**Read `google-cloud-console-oauth` first, then this file.** It owns the console mechanics and this file does not
repeat them:

- The Cloud project and organization, enabling the APIs a scope belongs to, and who may administer the project.
- The Google Auth Platform pages (Branding, Audience, Data Access, Clients), the **Web application** client, and the
  redirect-URI matching rules with the per-data-center callback list.
- The generic scope model: declaring every scope, the three tiers and what each costs, the rule that an app takes the
  tier of its most sensitive scope, **the tier of every Drive scope**, and the refresh-token conditions on the
  authorize URL.
- The client secret's one-shot visibility and how rotation works without re-consenting customers.
- Publishing status and audience, the user caps, brand and scope verification, and the annual third-party security
  assessment that a restricted scope drags in.
- The generic OAuth failure table — including what a `403` carrying a quota reason means and what not to do about it.

If you are reading only this file, you are missing all of the above.

**Read `google-drive-oauth-app` too the moment a Drive scope enters the picture.** It owns the Drive-side depth: what
each Drive scope costs, the permitted-application-type gate that no paperwork can satisfy, the `drive.file` + Picker
trade-off, shared drives, and the domain-ownership problem. This file says *which* Drive scope each product shape
needs; that file says what one costs.

## Inputs to collect before you start

The base skill lists the console inputs. These are the Slides-specific ones, and the first two decide the tier:

| Input | Notes |
| --- | --- |
| **Where do presentation IDs come from?** | The user pastes or picks one, an upstream record carries it, the app created the deck — or the app must discover them. This is the Drive-dependency question (§2) |
| **Read decks, or generate and edit them?** | `presentations.readonly` vs `presentations`; and on the Drive side, read vs write (§1, §2) |
| **Must generated decks land in a particular Drive folder or shared drive?** | Creating is Slides; *placing* the file is a Drive call with Drive scopes (§2) |
| **Is any output a rendered file or an image?** | PPTX/PDF/ODP/TXT is a Drive export; per-slide images are the thumbnail method and nothing else (§4) |
| **Does the product re-edit decks other people are also editing?** | Decides whether revision pinning is optional or mandatory (§3) |
| **Expected read, thumbnail and write volume per customer** | Thumbnails draw on a separate, much smaller quota bucket (§6) |
| **Do comments, speaker notes or slide transitions matter?** | One is preview-only, one is partly writable, one does not exist (§5) |

## Quick Start

1. Work the base skill's console steps, and **enable the Google Slides API** on the project — plus the Google Drive
   API if §2 lands on any Drive scope. A perfect client against a project with the API off fails at the first call,
   not at authorization.
2. Settle §2 — the Drive dependency — **before** declaring anything on Data Access. It decides the whole project's
   tier, and the base skill's §5 is where you look up what that tier costs.
3. If the answer is a whole-Drive scope, switch to `google-drive-oauth-app` for the application-type gate and the
   assessment ownership, and start verification now rather than after launch.
4. Declare the narrowest Slides scope the product needs — and check §2's redundancy trap before declaring one at all.
5. Finish the base skill's capture, round-trip and handoff steps, adding the Slides checks in §7.

## Slides platform state (verified 2026-09-20 — re-verify before trusting)

- **Slides scope tiers, from the Slides API's own scope page:** `https://www.googleapis.com/auth/presentations` and
  `https://www.googleapis.com/auth/presentations.readonly` are both **Sensitive**. The same page also lists the two
  Sheets scopes (for linked charts) and three Drive options; for what those Drive labels mean and cost, see the base
  skill's §5 and `google-drive-oauth-app`. **There is no restricted Slides scope** — the restricted tier only ever
  arrives through Drive.
- **The `presentations` resource exposes exactly three methods**: `presentations.create`, `presentations.get` and
  `presentations.batchUpdate`, plus `presentations.pages.get` and `presentations.pages.getThumbnail` on the pages
  sub-resource. **There is no list, no search, no copy, no export, no delete and no change-notification method.**
- **`presentations.get`, `pages.get` and `getThumbnail` accept any one of** `presentations`, `presentations.readonly`,
  `drive`, `drive.readonly` or `drive.file`. **`presentations.create` accepts** `presentations`, `drive` or
  `drive.file`. **`batchUpdate` accepts** those three plus `drive.readonly`, `spreadsheets` and
  `spreadsheets.readonly` — the Sheets entries are there for linked-chart requests, not as a substitute for a Slides
  write scope.
- **`getThumbnail` returns a URL, not bytes, and "the URL to the image has a default lifetime of 30 minutes."** Sizes
  are `LARGE` (1600px wide), `MEDIUM` (800px) and `SMALL` (200px); PNG is the only MIME type.
- **Drive exports a presentation to PPTX, ODP, PDF and plain text — and nothing else.** There is no PNG, JPEG or SVG
  export for a presentation; Drive lists those only for drawings.
- **Slides quotas:** 3,000 read requests/minute/project and 600/minute/user/project; **a separate "expensive read"
  bucket covering `getThumbnail` at 300/minute/project and 60/minute/user/project**; 600 write requests/minute/project
  and 60/minute/user/project.
- **Comment threads on a presentation are Developer Preview.** `presentations.get` and `pages.get` take a
  `commentsViewMode` parameter, and `batchUpdate` carries comment requests, all flagged Developer Preview.

If the scope table or the method list does not look like this, stop and report what you actually see rather than
proceeding.

## 1. The Slides scopes

| Scope | Grants | Tier |
| --- | --- | --- |
| `https://www.googleapis.com/auth/presentations.readonly` | See all the user's Google Slides presentations | **Sensitive** |
| `https://www.googleapis.com/auth/presentations` | See, edit, create and delete all the user's Google Slides presentations | **Sensitive** |

Two consequences, both easy to get backwards:

- **Neither is restricted.** A Slides integration that never touches Drive stays in the sensitive tier, which by the
  base skill's §5 is a materially cheaper project than a restricted one. Worth establishing before anyone budgets for
  a restricted-tier review out of habit — the Slides half of this integration never needs one.
- **Both are all-presentations scopes.** `presentations.readonly` reads *every* deck the user can open, given its ID.
  "Read-only" narrows the write risk, not the breadth. The only per-file access that exists for Slides comes from the
  Drive side (§2), and Google's own recommendation on the Slides scope page is to prefer the per-file
  option where a product can live with one.

## 2. The Drive dependency — the decision that sets the project's tier

**This is the centrepiece. Raise it as a product decision; do not make it on the owner's behalf.**

The Slides API can `get` a presentation, `create` a blank one, read a page, thumbnail a page and `batchUpdate` one.
All of it is addressed by `presentationId`. It cannot answer "which decks does this customer have?", "which template
is called Q3 Review?", "give me this as a PPTX", "put the deck I just made in the Sales folder" or "duplicate this
template". Google's own Slides guides point at Drive for every one of those: `files.list` with a `mimeType` query to
find presentations, `files.copy` to duplicate one, `files.update` or `files.create` to place one in a folder,
`files.export` to render one.

That last one is not optional for most template products. **A presentation created through the Slides API lands in
the user's root Drive folder** — moving it anywhere else, including into a shared drive, is a Drive call needing Drive
scopes.

So the real question is not *which Slides scope* but **where presentation IDs come from, and where output has to go**:

| Path | Scopes beyond the Slides one | What it costs | What the product can do |
| --- | --- | --- | --- |
| **A. Discover through Drive** | a whole-Drive scope — read or write; look its tier up in base §5 before budgeting | The heaviest path: the base skill's restricted-tier review **plus** the permitted-application-type gate in `google-drive-oauth-app` §2 | Enumerate, search, sync, copy templates, file output into folders and shared drives, export, read comments. The full product. |
| **B. Per-file through the Picker** | `drive.file` | Base §5 and the Drive skill; materially the lightest option Google offers here | Only decks the user explicitly picked, decks shared with the app, and decks the app created — including creating, editing, thumbnailing and exporting those. **No enumeration, ever.** |
| **C. No Drive scope at all** | none | Sensitive, from the Slides scope alone | Read or edit a deck **whose ID the app already has**, and create new decks in the user's root folder. No listing, no copying a template, no folder placement, no export, no comments. |

Path **A** is what "sync the customer's decks" and "clone our template into their Drive" both mean, and the Drive
skill's application-type gate applies before any budget conversation — an app outside the permitted categories cannot
obtain those scopes at any price.

Path **B** is a different product, not a cheaper configuration: the user hands over one file at a time through the
Google Picker. Worth knowing how little Slides capability it loses — **`drive.file` is accepted by every Slides
method**, `get`, `pages.get`, `getThumbnail`, `create` and `batchUpdate` alike, and it is also accepted by Drive's
`files.export`. Everything path B gives up, it gives up on the Drive side: finding files the user never handed over.

Path **C** is the one people forget and is exactly right for some products. A deck generator that is handed a template
ID by an upstream system, or that only ever operates on decks it created and recorded the IDs of, never needs a Drive
scope. `presentations.create` returns the created presentation including its `presentationId`, so an app that makes
its own decks can keep working without ever listing anything — as long as root-folder placement is acceptable.

### The redundancy trap

**A whole-Drive read scope already authorizes `presentations.get`, `pages.get` and `getThumbnail`; a whole-Drive write
scope already authorizes `create` and `batchUpdate` as well.** An app that has already accepted whole-Drive scopes
gains **nothing** by also declaring `presentations` or `presentations.readonly`. It adds a line to the consent screen,
a scope to justify at review, and a scope to re-justify at every renewal, for zero new capability. Check it against
the real call list before declaring; it is one of the few scope reductions that costs nothing.

The inverse trap is quieter and worse: **`presentations.readonly` does not authorize `files.export`.** An app that
declared Slides scopes only and then adds "download as PPTX" discovers mid-sprint that the feature needs a Drive
scope — `drive.file` if the deck was picked or app-created, otherwise a whole-Drive one and the review that comes
with it.

### Switching later is a re-consent event

Moving a live integration between these paths changes the requested scope set, which re-consents every connected
customer, and moving to path B adds a Picker to the UI. Say so plainly rather than proposing it as a configuration
tweak.

## 3. The presentation model, object IDs, and index arithmetic across calls

You do not need to implement Slides to register its client, but the shape of the API explains most of the support
tickets that follow, and a verification demo video has to show it working.

- A presentation is **pages containing page elements**, not a document flow. Pages come in four kinds — **slides**,
  **layouts**, **masters** and **notes pages** — and elements are `Shape`, `Image`, `Video`, `Line`, `Table`,
  `WordArt`, `SheetsChart` or a `Group` of them. Text lives inside shapes and table cells, nowhere else.
- **Notes masters are read-only in the Slides API**, and on a notes page **only the text in the speaker-notes shape
  can be modified.** A product that wants to restyle handouts cannot.
- **Object IDs can be supplied by the caller**, and that is the trick that makes multi-step batches work: a
  `CreateSlideRequest` can name its own `objectId`, and a later request in the *same* batch can address it. Google's
  rules: unique among all pages and page elements in the presentation, starting with `[a-zA-Z0-9_]`, remaining
  characters also allowing `-` and `:`, **length between 5 and 50 characters inclusive**. Omit it and Google
  generates one. A connector that mints IDs from a customer string will eventually produce a 4-character ID or a
  collision, and the whole batch fails.
- **`batchUpdate` is ordered and atomic.** "Each request is validated before being applied. If any request is not
  valid, then the entire request will fail and nothing will be applied." The server processes subrequests in the
  order given, so a later subrequest can depend on an earlier one — and replies come back positionally, some empty.
- **Text positions are indexes, and they are fragile.** `InsertTextRequest.insertionIndex` is zero-based, measured
  **in Unicode code units** against the shape's `TextElement` indexes, and Google notes the index "may be adjusted to
  prevent insertions inside Unicode grapheme clusters", inserting immediately after the cluster instead. Some control
  characters and Private Use Area characters are silently stripped from inserted text. Offsets computed with a
  different string model, or assumed to survive an emoji, land in the wrong place without erroring.
- **Across calls, indexes and object IDs go stale.** Any collaborator — or a second process of your own — editing
  between your `get` and your `batchUpdate` invalidates what you computed, and the API will cheerfully apply it
  somewhere else. The answer is `WriteControl`: keep the `revisionId` from the `get` and send it back as
  `requiredRevisionId`, and the write is refused with a **400** if the deck moved. An integration that edits decks
  humans also edit and never pins a revision is not "usually fine"; it is silently corrupting slides under
  concurrency. Google is explicit that with collaborators present "the presentation might not exactly reflect your
  changes."
- **`presentations.create` makes a blank deck with the given title** and nothing else; content arrives via
  `batchUpdate`. Create-then-populate is two calls, always.

## 4. Rendering: thumbnails are not export

Two different operations that people ask for interchangeably:

- **`presentations.pages.getThumbnail`** renders **one page** to a PNG and returns a **URL with a default lifetime of
  30 minutes**, at 1600px, 800px or 200px wide. It is the only image rendering the Slides API does. Two design
  consequences: a product that stores thumbnails must fetch the bytes promptly rather than persisting the URL, and a
  product that thumbnails a whole deck pays one call per slide against the small "expensive read" bucket (§6).
- **`files.export` on the Drive API** renders a whole presentation to **PPTX, ODP, PDF or plain text** — and it is a
  Drive call with Drive scopes, not a Slides one. There is **no image export for a presentation**; "give me a PNG of
  every slide" is the thumbnail loop above, not an export.

So "let users download the deck" and "show a slide preview" are two different features with two different scope
stories, and only the second is reachable without Drive.

## 5. What the API does not do that people expect

Half the scoping arguments on a Slides project come from assuming one of these exists:

- **No enumeration, search or copy.** All three are Drive (§2). There is no Slides equivalent of "list my decks."
- **No change notifications.** The Slides API has no watch method. Detecting that a deck changed means polling — a
  `get` to compare `revisionId`, or Drive-side change tracking with a Drive scope.
- **No slide transitions or element animations.** Google's `Request` catalog has no request for either. A deck
  generated through the API is static; transitions have to be in the template the deck was copied from, which is
  itself a Drive `files.copy`.
- **No presenting or slideshow control**, and no access to revision history — revisions are a Drive resource.
- **No image export**, per §4.
- **Comments are Developer Preview.** `commentsViewMode` on `presentations.get` and `pages.get`, and the comment
  requests in `batchUpdate`, are all part of Google's Developer Preview Program. Do not plan a launch on them; if
  comments must ship, the Drive comments API and its Drive scopes are today's answer.
- **Speaker notes are partly writable and handouts are not** (§3).

## 6. Quotas

| | Per minute per project | Per minute per user per project |
| --- | --- | --- |
| **Read requests** | 3,000 | 600 |
| **Expensive read requests (`getThumbnail`)** | 300 | 60 |
| **Write requests** | 600 | 60 |

What matters when sizing a multi-tenant connector:

- **The thumbnail bucket is the one that breaks first.** Sixty thumbnails a minute for one customer's user is one
  60-slide deck per minute — a "generate previews for the whole library" feature hits the ceiling immediately, and it
  is a tenth of the ordinary read allowance.
- **The per-user-per-project limits bind before the project ones** for a single customer's initial sync.
- **A whole `batchUpdate` counts as one request**, however many subrequests it carries, and it is authenticated once.
  Batching is a quota strategy as much as a latency one — and it is also what keeps an edit atomic.
- Google's documented remedy for exceeding a Slides quota is **exponential backoff**, and its documented status code
  here is `429`. The base skill's symptom table covers the other code Google sometimes uses and what not to do when
  you see it.
- These are Slides quotas only. Discovery, copying, folder placement and export consume **Drive** quota, counted
  separately.

## Product fact — what the Slides connector asks for

> **As of 2026-09-20, Unified.to's Google Slides connector requests:**
>
> - **File read:** `openid`, `profile`, `email`, `https://www.googleapis.com/auth/drive.readonly`,
>   `https://www.googleapis.com/auth/drive.labels.readonly`, `https://www.googleapis.com/auth/presentations.readonly`
> - **File write:** `openid`, `profile`, `email`, `https://www.googleapis.com/auth/drive`,
>   `https://www.googleapis.com/auth/drive.labels.readonly`, `https://www.googleapis.com/auth/presentations`
> - **Employee-directory read:** `openid`, `profile`, `email`, `https://www.googleapis.com/auth/drive.readonly` —
>   note there is **no Slides scope in this configuration at all**; it resolves people from the Drive file surface.
> - **Login/identity only:** `openid`, `profile`, `email`
>
> **This is a path A connector (§2).** It reaches presentations as Drive files filtered to the Google Slides MIME
> type, so the whole-Drive scopes are load-bearing and every configuration except login-only inherits whatever the
> base skill's §5 says a whole-Drive scope costs — including the permitted-application-type gate in
> `google-drive-oauth-app` §2. The Slides scopes it requests alongside them sit at the sensitive tier and do not raise
> that; by the redundancy trap in §2 they are also already implied by the Drive scopes it holds, so confirm with the
> connector's owner whether they are still needed before justifying them at review.
>
> There is **no `drive.file` variant**, so path B is not available without a change on the connector side. The
> connector does support a **Google service-account credential** as an alternative to the user OAuth flow, minting
> tokens for the presentations, drive and drive-labels-read scopes — the domain-wide route discussed in
> `google-drive-oauth-app` §5.
>
> Two auth quirks worth carrying into the handoff: the authorize request is built with `access_type` and `prompt`
> parameters, so the base skill's refresh-token conditions are already wired in and should be verified rather than
> assumed; and the connector remaps Google's quota-flavoured `403` responses to `429` so reads back off instead of
> being mistaken for an authorization failure.
>
> Scope sets change. This note is dated, not live — **confirm the current set with the connector's owner** before
> declaring scopes or submitting anything for review.

## 7. Slides-specific end-to-end checks

On top of the base skill's authorize → refresh round trip, and the Drive checks in `google-drive-oauth-app` §7 if a
Drive scope is in play:

1. **Enable both APIs you actually call.** Slides API always; Drive API if discovery, copying, folder placement,
   export or comments are in scope. A missing enablement fails at the first call, long after consent looked fine.
2. `presentations.get` a real deck and confirm the page tree comes back — not just a 200 on the token exchange.
3. **Test discovery the way the product will do it.** On path B, confirm a Picker-selected deck is readable **and
   that a never-picked one is not**. Testing only against a deck the app itself created passes on `drive.file` and
   proves nothing.
4. If the product generates decks, confirm **where the file lands** and that moving it to the intended folder or
   shared drive is authorized. Root-folder-only output is a product defect discovered in week two otherwise.
5. If previews are a feature, call `getThumbnail` and confirm the client **fetches the bytes inside the 30-minute
   window** rather than storing the URL — then thumbnail a deck with enough slides to touch the expensive-read
   ceiling (§6).
6. If export is a feature, run a real `files.export` to PPTX and to PDF, and confirm it is authorized by the Drive
   scope you declared — not by the Slides one.
7. If the app writes, do a `get` → `batchUpdate` round trip **with `requiredRevisionId` set**, and prove the failure
   path by editing the deck between the two calls.
8. Inspect the granted `scope` in the token response against what was requested; a granular-consent screen lets the
   user drop one, and a partial grant fails later on a call rather than at consent.

| Symptom | Cause |
| --- | --- |
| Auth succeeds, every Slides call fails | Google Slides API not enabled on the project |
| "We can't find any of the customer's presentations" | No Slides method lists anything — discovery is Drive (§2) |
| `presentations.get` works, PPTX or PDF export 403s | `files.export` does not accept the Slides scopes; it needs a Drive scope (§4) |
| Generated decks all appear in the user's root Drive folder | Expected — placing a file is a Drive call with Drive scopes (§2) |
| Thumbnail URLs 404 for saved previews | The URL's default lifetime is 30 minutes; fetch the bytes, do not persist the URL (§4) |
| Previews throttle far sooner than reads do | `getThumbnail` draws on the separate expensive-read bucket (§6) |
| `400` on a write that worked a moment ago | `requiredRevisionId` no longer matches — the deck was edited between calls (§3) |
| Edits land on the wrong text under collaboration | Stale indexes computed before a collaborator's edit, with no revision pinned (§3) |
| Offsets drift on slides containing emoji | Indexes are Unicode code units and may shift to avoid splitting grapheme clusters (§3) |
| Whole batch rejected for one bad subrequest | `batchUpdate` is atomic by design (§3) |
| `CreateSlideRequest` rejected for a valid-looking ID | Object IDs must be 5–50 characters and unique in the presentation (§3) |
| Created deck is empty despite content in the request | `create` makes a blank deck; populate with `batchUpdate` (§3) |
| Transitions and animations never appear on generated decks | The API has no request for either — they must come from the copied template (§5) |
| Comments never appear | Comment support in the Slides API is Developer Preview (§5) |

## Stop and ask

Beyond the base skill's list and the Drive skill's list:

- **Nobody has answered where presentation IDs come from, or where generated decks must land.** Register nothing
  until §2 is settled — it decides the tier for the whole project and is close to irreversible once customers are
  connected.
- The product needs Drive-wide discovery or template copying and there is **no confirmed budget and named owner** for
  what the base skill's §5 says that costs, or the app may not qualify as a **permitted application type** for
  whole-Drive scopes.
- Someone proposes adding `presentations` / `presentations.readonly` to an app that already holds whole-Drive scopes
  — confirm against the real call list first; it is usually pure review surface for no capability (§2).
- A launch plan depends on **Developer Preview** comment functionality (§5), or on transitions, animations, image
  export or change notifications the API does not have (§5).
- Someone wants to move live connections between §2's paths — that re-consents every customer and, for path B,
  changes the product's UI.
- The Slides scope tiers or the method-to-scope mapping do not match the **Slides platform state** section above.

## References

Slides-specific only; the base skill carries the generic Google OAuth references and `google-drive-oauth-app` carries
the Drive scope and assessment references. Verified to resolve on 2026-09-20.

- Choose Google Slides API scopes (the `presentations` tiers and the Drive options) — https://developers.google.com/workspace/slides/api/scopes
- Slides API introduction (pages, page elements, notes pages read-only, batch updates) — https://developers.google.com/workspace/slides/api/guides/overview
- Create and manage presentations (root-folder placement, moving via Drive, copying via `files.copy`) — https://developers.google.com/workspace/slides/api/guides/presentations
- Text structure and styling (`TextElement` sequences, indexes, inserting text) — https://developers.google.com/workspace/slides/api/concepts/text
- Page elements — https://developers.google.com/workspace/slides/api/concepts/page-elements
- Transforms (page element positioning) — https://developers.google.com/workspace/slides/api/guides/transform
- Merge data into Slides (`ReplaceAllText` and template-driven generation) — https://developers.google.com/workspace/slides/api/guides/merge
- `presentations` REST resource — the three-method list — https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations
- `presentations.get` (authorization scopes) — https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/get
- `presentations.create` (scopes; creates a blank presentation) — https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/create
- `presentations.batchUpdate` (scopes, atomicity, `WriteControl.requiredRevisionId`) — https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/batchUpdate
- `Request` reference (caller-supplied object IDs, `insertionIndex` in Unicode code units) — https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations/request
- `presentations.pages.get` (scopes, `commentsViewMode`) — https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations.pages/get
- `presentations.pages.getThumbnail` (30-minute URL lifetime, sizes, PNG only) — https://developers.google.com/workspace/slides/api/reference/rest/v1/presentations.pages/getThumbnail
- Batch requests (one batch = one request, ordered subrequests, single authentication) — https://developers.google.com/workspace/slides/api/guides/batch
- Use field masks (partial reads and writes) — https://developers.google.com/workspace/slides/api/guides/field-masks
- Improve performance — https://developers.google.com/workspace/slides/api/guides/performance
- Slides API usage limits (read, expensive-read and write quotas; backoff) — https://developers.google.com/workspace/slides/api/limits
- Manage comments (Developer Preview, `commentsViewMode`) — https://developers.google.com/workspace/slides/api/guides/comments
- Troubleshoot Slides authentication and authorization — https://developers.google.com/workspace/slides/api/troubleshoot-authentication-authorization
- Drive `files.export` reference (Drive-only scopes) — https://developers.google.com/workspace/drive/api/reference/rest/v3/files/export
- Drive export MIME types (PPTX, ODP, PDF, TXT for presentations — no image export) — https://developers.google.com/workspace/drive/api/guides/ref-export-formats
- Search for files and folders (the `mimeType` query used for deck discovery) — https://developers.google.com/workspace/drive/api/guides/search-files
- Google Workspace Developer Preview Program — https://developers.google.com/workspace/preview
