Skip to content

feat: manage project API tokens - #74

Merged
bjarn merged 2 commits into
mainfrom
feat/project-api-tokens
Oct 30, 2026
Merged

bjarn merged 2 commits into
mainfrom
feat/project-api-tokens

Conversation

@bjarn

@bjarn bjarn commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

What changed

Non-breaking. Suggested version: 3.3.0 (minor).

  • Regenerates co.lettermint.types from the latest API spec (separate commit, generated files only).
  • Adds projects().apiTokens(), a ProjectApiTokens sub-resource for a project's API tokens: list(projectId), iterate(projectId), create(projectId, body) and delete(projectId, tokenId). It follows team().invites(): each method has the usual overloads with and without ListProjectApiTokensQuery and RequestOptions, validates the project and token IDs before sending, and uses the team token.
  • create returns the token value once (data().token()). Use it to send through the API, or as the SMTP password when SMTP is enabled for the project; smtp() then holds the host, ports and username. Like the other credential records, ProjectApiTokenSecret.toString() prints the token as [redacted].
  • The rotateToken Javadoc now points at apiTokens() for managing specific tokens.
  • The team API token operations are added by the PR stacked on top of this one. Until then, the operation coverage test in TeamApiTest lists those three operations as pending; everything else stays strictly checked.

No existing generated record changes shape, so no canonical record constructor gains an argument.

API changes in the regenerated types

Operation / type Change SDK method
GET /projects/{projectId}/api-tokens New: a project's API tokens without their values, cursor paginated (page[size], page[cursor], sort) projects().apiTokens().list / iterate (this PR)
POST /projects/{projectId}/api-tokens New: create a project API token (201). The token is only returned once. 422 projects().apiTokens().create (this PR)
DELETE /projects/{projectId}/api-tokens/{tokenId} New: delete a project API token; it stops working immediately projects().apiTokens().delete (this PR)
GET /team/api-tokens New: the team's API tokens without their values, cursor paginated (page[size], page[cursor], sort) team().apiTokens().list / iterate (stacked PR)
POST /team/api-tokens New: create a team API token (201) with a subset of the requesting token's abilities. The token is only returned once. 422 team().apiTokens().create (stacked PR)
DELETE /team/api-tokens/{tokenId} New: delete a team API token; it stops working immediately team().apiTokens().delete (stacked PR)
POST /projects/{projectId}/rotate-token The API's description now points at the project API token endpoints. No change in the generated Java code existing projects().rotateToken (deprecated)
New types ProjectApiToken, ProjectApiTokenSecret, ProjectApiTokenCreatedResponse, SmtpCredentials, StoreProjectApiTokenData, ListProjectApiTokensQuery, ListProjectApiTokensQuerySortItem, TeamApiToken, TeamApiTokenSecret, TeamApiTokenCreatedResponse, StoreTeamApiTokenData, ListTeamApiTokensQuery, ListTeamApiTokensQuerySortItem, ApiTokenSource

ProjectApiTokenSecret and TeamApiTokenSecret print token as [redacted] in toString(). The other generated files only change their spec header.

Usage

ProjectApiTokenCreatedResponse created = lettermint.projects().apiTokens().create(projectId,
    StoreProjectApiTokenData.builder().name("Production").build());
String token = created.data().token(); // store it now; it is only returned once

for (ProjectApiToken apiToken : lettermint.projects().apiTokens().iterate(projectId)) {
    System.out.println(apiToken.name() + " " + apiToken.lastUsedAt());
}

lettermint.projects().apiTokens().delete(projectId, created.data().id());

Checks

  • ./gradlew generateTypes with the latest spec, then ./gradlew checkGeneratedTypes: up to date (231 files)
  • ./gradlew clean build --no-daemon on JDK 17: passed (107 tests, 0 failures)
  • ./gradlew clean build --no-daemon on JDK 24: passed (107 tests, 0 failures)
  • CI build-output checks on the jar: Automatic-Module-Name: co.lettermint present, no okhttp bundled

Not run locally

  • JDK 21 and 25 (CI matrix); not installed locally. JDK 17 and 24 passed.
  • Windows (CI matrix).
  • ./gradlew checkstyleMain checkstyleTest: the build has no checkstyle tasks, and the workflow ignores the result (|| true).

Suggested release tag

v3.3.0, after the whole stack has merged.

@bjarn
bjarn requested a review from a team as a code owner October 29, 2026 16:53
@bjarn
bjarn added this pull request to stack #76 October 29, 2026 16:53
@bjarn
bjarn force-pushed the feat/project-api-tokens branch from 333801a to 5f484e2 Compare October 29, 2026 22:05
@bjarn
bjarn merged commit 90b30c1 into main Oct 30, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants