Skip to main content
POST
/
v1
/
auth
/
slack
/
start
Start Authentication Flow
curl --request POST \
  --url https://api.example.com/v1/auth/slack/start \
  --header 'Content-Type: application/json' \
  --data '
{
  "email": "<string>",
  "codeChallenge": "<string>",
  "cliCallbackUrl": "<string>"
}
'
{
  "authorizeUrl": "<string>",
  "state": "<string>"
}
Starts the Slack OAuth 2.0 authentication flow with PKCE protection. This endpoint creates an OAuth session and returns a Slack authorization URL that the client should open in a browser.

Endpoint

POST /v1/auth/slack/start

Rate Limits

  • 10 requests per minute per IP address
Excessive requests will result in 429 Too Many Requests responses. Implement exponential backoff for retries.

Request Body

email
string
required
User’s email address. Must end with the configured ALLOWED_EMAIL_DOMAIN.Validation: Must be a valid email format.
codeChallenge
string
required
PKCE code challenge derived from the code verifier.Computation: base64url(SHA256(code_verifier))Validation: Minimum 10 characters (typically 43 characters for a properly generated challenge).Example: "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
cliCallbackUrl
string
required
Localhost URL where the CLI is listening for the OAuth callback.Format: Must be a valid URL (e.g., http://127.0.0.1:56789/callback)Usage: The API will redirect the browser to this URL after successful Slack authentication, appending code and state query parameters.

Response

authorizeUrl
string
required
Slack OAuth authorization URL. Open this URL in the user’s browser to begin authentication.Format: https://slack.com/openid/connect/authorize?response_type=code&client_id=...&scope=openid+profile+email&state=...&redirect_uri=...
state
string
required
OAuth state parameter for CSRF protection. The CLI should verify this matches the state received in the callback.Format: 24-byte base64url-encoded random string (32 characters)Expiration: 10 minutes from creation

Example Request

curl -X POST https://api.rs-tunnel.example.com/v1/auth/slack/start \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "codeChallenge": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM",
    "cliCallbackUrl": "http://127.0.0.1:56789/callback"
  }'

Example Response

200 Success
{
  "authorizeUrl": "https://slack.com/openid/connect/authorize?response_type=code&client_id=123456789.987654321&scope=openid+profile+email&state=Ab3kDf9mPqRsTuVwXyZ123456789&redirect_uri=https%3A%2F%2Fapi.rs-tunnel.example.com%2Fv1%2Fauth%2Fslack%2Fcallback",
  "state": "Ab3kDf9mPqRsTuVwXyZ123456789"
}
400 Invalid Email Domain
{
  "code": "EMAIL_NOT_ALLOWED",
  "message": "Email domain @acme.com is not allowed. Expected @example.com."
}
400 Invalid Input
{
  "code": "INVALID_INPUT",
  "message": "Invalid auth start request payload.",
  "details": {
    "fieldErrors": {
      "codeChallenge": ["String must contain at least 10 character(s)"]
    }
  }
}
429 Rate Limit Exceeded
{
  "code": "RATE_LIMIT_EXCEEDED",
  "message": "Too many requests. Please try again later."
}

PKCE Code Challenge Generation

The codeChallenge must be computed using SHA-256 hashing:
import { createHash, randomBytes } from 'node:crypto';

// Generate code verifier (store this securely!)
const codeVerifier = randomBytes(32).toString('base64url');
// Example: "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

// Compute code challenge
const codeChallenge = createHash('sha256')
  .update(codeVerifier)
  .digest('base64url');
// Example: "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
Store the codeVerifier securely! You will need it in the token exchange step. Never send the verifier during the start flow.

Error Codes

CodeHTTP StatusDescription
EMAIL_NOT_ALLOWED403Email domain does not match ALLOWED_EMAIL_DOMAIN
INVALID_INPUT400Request body validation failed
RATE_LIMIT_EXCEEDED429Too many requests within the time window

Implementation Flow

  1. Generate PKCE pair: Create codeVerifier (random) and codeChallenge (SHA-256 hash)
  2. Start local server: Listen on localhost for the OAuth callback
  3. Call this endpoint: Send email, challenge, and callback URL
  4. Open browser: Direct the user to the returned authorizeUrl
  5. Wait for callback: Your local server will receive the login code
  6. Exchange code: Call POST /v1/auth/exchange with the login code and verifier
The OAuth session expires after 10 minutes. Ensure the user completes the Slack authorization and the CLI exchanges the login code within this timeframe.

Next Steps

Token Exchange

After receiving the login code in your callback, exchange it for access tokens

Build docs developers (and LLMs) love