CtrlK
BlogDocsLog inGet started
Tessl Logo
SkillPublic

dev-console-subscribe-api

Use when the user wants to add, subscribe, enable, or integrate an Adobe API — phrases like "add Analytics", "subscribe Firefly", "enable API", "add API to project", "create credential", "set up OAuth S2S", "subscribe to service", "add service", "connect API", "integrate Adobe API", "I need access to", "set up credentials for", "create project", "create a new project", "new project", "set up a project", "provision API", "provision access", "get API access", "generate credentials", "new credential", "create OAuth", "create S2S". Handles the full flow — finding the API, picking a credential type, selecting a product profile, creating a credential if needed, and subscribing to the API.

Quality

92%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide
SecuritybySnyk

Low

Low-risk findings worth noting

SKILL.md
Quality
Evals
Security

Subscribe API Flow

Guide the user through subscribing an Adobe API to a credential in their workspace, step by step.

Before starting: invoke the dev-console-context skill.

Steps

  1. Get org — Call get_organisations and ask the user which org to use.

  2. New or existing project? — Ask the user:

    1. Create a new project
    2. Use an existing project

    If new project (1):

    • Ask the user for a title only (e.g. "My Analytics Project"). Do NOT ask for a name.
    • Derive the name from the title automatically: strip all non-alphanumeric characters, camelCase or concatenate words, truncate to 20 characters. For example: "My Analytics Project" → "MyAnalyticsProject".
    • Call create_project with projectType: "default", the derived name, and the user's title.
    • The response returns both projectId and workspaceId directly — the default workspace is always Production. Do NOT call list_workspaces unless the credential type is User Auth (AdobeId), in which case call list_workspaces to confirm the available workspaces.

    If existing project (2):

    • Ask:
      1. All projects
      2. My projects (created or modified by me)
      • 1 → call get_projects with filterBy: "all"
      • 2 → call get_projects with filterBy: "me"
    • Show the returned project list as a numbered list (names only, no raw IDs) and ask the user which project they want.
    • Call list_workspaces with the chosen project → show workspace list as a numbered list → ask which workspace to use.
    • Once the workspace is selected, automatically (without asking):
      1. Call get_credentials for that workspace.
      2. For each credential in the response, call get_credential_services with its id_integration. Only show credentials returned by get_credentials — do NOT include org-level credentials.
      3. Display a summary like:
        Here's what's already set up in this workspace:
        
        📋 Credential: "My S2S Cred" (OAuth Server-to-Server)
           APIs subscribed: Adobe Analytics, Firefly API
        
        📋 Credential: "My Web App" (AdobeId)
           APIs subscribed: none
        If get_credentials returns an empty list, say: "No credentials found in this workspace yet."
      4. Then proceed to ask which API they want to add.
  3. Find the API — If the user asks "what APIs are available", "show me available APIs", or similar, call list_services with filterBy: "enabled" and display only the enabled APIs as a list (name + description, no raw codes). If the user named a specific API, call list_services with filterBy: "enabled" to find its code and full details. Never guess an SDK code.

  4. Pick credential type — Always run this step based on the API's supported types — never skip it because an existing credential was found. An API can have multiple enabled instances with different type values. Collect ALL enabled instances for the API code, then:

    • Any instance whose type is admin_entp → do not offer it as a selectable option, but show a note to the user:
      ⚠️  Admin Enterprise credential is also available for this API but is not yet
          supported in this connector. You can still subscribe to it via the
          Adobe Developer Console.
    • If no instances remain after setting aside admin_entp → tell the user:
      This API only supports Admin Enterprise credentials, which are not yet supported
      in this connector. You can subscribe via the Adobe Developer Console directly.
      and stop.
    • If only one remaining credential type → proceed with it automatically.
    • If multiple remaining credential types → show them as a numbered list and ask: "This API supports multiple credential types. Which would you like to use?"
      1. Analytics credential (internal: analytics) — if an analytics instance is present
      2. User Auth (AdobeId) — for user-facing apps (internal: adobeid)
      3. OAuth Server-to-Server — for server-to-server access (internal: oauth_server_to_server, also used for entp)
    • Wait for the user to pick before proceeding. Do not auto-select based on what credentials already exist in the workspace.
    • Show only credential type names in this list — never mention existing credentials here. Do not append "subscribe to the existing X credential" or any reference to existing workspace credentials. Existing credential lookup happens in step 6, after the type is chosen.
  5. Check for product profiles — After the credential type is decided, inspect its properties.licenseConfigs array from the matching API instance:

    • If it is non-empty: present the profiles as a numbered list (show name, never raw id or productId) and tell the user: "You can select one or more of these profiles." Collect their choices — you'll need the selected profiles' id and productId fields when subscribing.
    • If it is empty or absent: skip directly to step 6 with no licenseConfigs.
    • This step must complete before any credential creation or subscription call — even when creating a new credential. Never pass services to create_oauth_s2s_credential until licenseConfigs have been resolved.
  6. Subscribe — All credentials are workspace-scoped, so always use the workspace-level tools:

    OAuth Server-to-Server credential (oauth_server_to_server) → call subscribe_credential_to_services:

    • Pass orgId, projectId, workspaceId, credentialType: "oauth_server_to_server", credentialId, and services.
    • Each service entry must include licenseConfigs if the user selected product profiles in step 5. An empty licenseConfigs: [] is NOT the same as omitting it — pass the user's selections.
    • The credentialType must always match the credential's actual type (oauth_server_to_server), never the API's type (entp).

    All credential types use subscribe_credential_to_services (PUT). The server automatically preserves all already-subscribed services — only pass the service(s) you want to add or change; do NOT pre-fetch and re-send the full existing list. Preservation is per-service, not per-licenseConfig: if you're adding a licenseConfig to an already-subscribed service, include that service's full intended licenseConfigs list (existing plus new), not just the new one.

  7. Report success — If subscribe_credential_to_services returns a 200, report success immediately without a separate verification call: "✓ [API name] has been successfully subscribed to your [credential type] credential." List all currently subscribed APIs from the services array you sent (no need to re-fetch). Only call get_credential_services if the response is ambiguous or an error was returned.

Unsubscribe API Flow

Trigger when the user wants to remove an API from a credential — phrases like "unsubscribe X", "remove Analytics from this credential", "stop using Firefly API", "disconnect this API".

  1. If org/project/workspace/credential context isn't already established, run Step 1–2 of the flow above to get there, then call get_credentials + get_credential_services (per the pairing rule) to show the user which credentials exist and what's subscribed to each.
  2. Ask the user which credential and which subscribed API(s) they want to remove — show names, never raw IDs or SDK codes.
  3. Tell the user exactly what is about to be removed — the API name(s), the credential, and the project, by name (never raw IDs or SDK codes) — and that it can't be undone. Do not ask them to type the project title or any other name. The client shows its own Yes / No approval prompt when you call the tool; that prompt is the confirmation.
  4. Call unsubscribe_credential_from_service with orgId, projectId, workspaceId, credentialType, credentialId, and sdkCodes (the codes to remove). This is the only tool used for unsubscribing, for every credential type. If the user declines the approval prompt, stop — do not retry or work around it — and ask what they would like to do instead.
    • Never build this manually by re-PUTting a reduced service list via subscribe_credential_to_services. Always use unsubscribe_credential_from_service.
    • For oauth_server_to_server credentials specifically, this tool internally calls the dedicated Console unsubscribe endpoint (unsubscribe_oauths2s_to_service) once per sdkCode, instead of the fetch-then-resubscribe path used for other credential types. You don't call that endpoint directly — always go through unsubscribe_credential_from_service; it selects the right path automatically based on credentialType.
  5. Report success: "✓ [API name] has been removed from your [credential type] credential." List the remaining APIs from the tool's response — no need to re-fetch.

Credential creation inputs

When no credential exists and one must be created, never ask the user for a name or description — derive them automatically using the pattern {projectName}-{type}[-{subtype}]:

Credential typePlatform / subtypeAuto-generated name example
OAuth S2S—mcptesting-s2s
AdobeIdWebAppmcptesting-adobeid-webApp
AdobeIdSinglePageAppmcptesting-adobeid-singlePageApp
AdobeIdNativeAppmcptesting-adobeid-native
AdobeIdapiKeymcptesting-adobeid-apikey
AnalyticsWebmcptesting-analytics-web
AnalyticsiOSmcptesting-analytics-ios
AnalyticsAndroidmcptesting-analytics-android

Set description to: "{Type} credential for {projectTitle}" (e.g. "OAuth S2S credential for mcptesting").

Truncate the name to 50 characters if needed. Use lowercase and hyphens only.

OAuth Server-to-Server (create_oauth_s2s_credential)

  • Auto-generate name and description. No further input needed — proceed directly to creation.
  • Never pass services to create_oauth_s2s_credential — always create the credential first (no services), then subscribe in a separate subscribe_credential_to_services call. Inline service attachment is unreliable and causes confusing retry flows.

User Auth — AdobeId (create_user_auth_credential)

  • Auto-generate name and description.
  • Ask only for platform. Present only platforms the API supports (from its platformList) as a numbered list:
    1. WebApp — web application
    2. SinglePageApp — SPA/React/Angular app
    3. NativeApp — desktop or mobile app
    4. apiKey — server-side API key access

Before asking for platform, if available_scopes is present:

  • Display a table of available scopes and tell the user: "All scopes are granted by default and cannot be deselected."

Platform-specific inputs — NEVER invent placeholder values, always wait for the user:

  • WebApp / SinglePageApp: ask for both:
    1. defaultRedirectUri — plain URL (e.g. https://example.com/callback)
    2. redirectUriList — one or more redirect URI patterns; pass as plain URLs, the server escapes dots automatically
  • NativeApp: no extra inputs required — proceed directly.
  • apiKey: ask for domain. No redirect URI needed.

Analytics (create_analytics_credential)

  • Auto-generate name and description.
  • Ask only for platform as a numbered list:
    1. Web — web app
    2. iOS — iOS mobile app
    3. Android — Android mobile app

Platform-specific inputs — NEVER invent placeholder values:

  • Web: ask for both:
    1. defaultRedirectUri — plain URL (e.g. https://example.com/callback)
    2. redirectUriList — one or more redirect URI patterns; pass as plain URLs, the server escapes dots automatically
  • iOS: ask for urlScheme. No redirect URI needed.
  • Android: no extra inputs required — proceed directly.

After creating any credential, use its returned id as credentialId in the subscription call. Never re-fetch credentials after a fresh creation.

Whenever any tool response includes a console_url field (project creation, credential creation, subscription), always display it to the user as a clickable link:

🔗 View in Adobe Developer Console: {console_url}

When Instructions Are Unclear

If you're unsure about an API, credential type, product profile, or Adobe concept during this flow — call search_adobe_docs before asking the user to clarify. For example:

  • User asks to subscribe an API you don't recognise → search "Adobe {API name} API developer documentation"
  • Unclear what scopes or product profiles an API requires → search "Adobe {API name} OAuth scopes product profile"
  • Unsure which credential type fits the user's use case → search "Adobe Developer Console credential types OAuth S2S user auth"

Always prefer fetching from official docs over guessing.


Rules

  • Do not assume anything not explicitly described in this skill — if a behavior, field, or API detail is unclear or not covered here, call search_adobe_docs to look it up in official Adobe documentation before proceeding.
  • entp APIs (e.g. Adobe Campaign) use an OAuth S2S credential. Never show "entp" to the user.
  • admin_entp instances are never selectable — always show a "coming soon" note with a link to the Console, but never block the rest of the flow. Only stop entirely if ALL instances are admin_entp.
  • Always use the API type field to determine credential type. Completely ignore oauthServerToServerOnly. Mapping: adobeid → create_user_auth_credential, analytics → create_analytics_credential, entp → create_oauth_s2s_credential, oauth_server_to_server → create_oauth_s2s_credential.
  • Never skip step 4. Credential type must be chosen based on the API's supported types every time — not inferred from what credentials already exist in the workspace.
  • Always pair get_credentials with get_credential_services. Whenever get_credentials is called, immediately follow up by calling get_credential_services for each credential returned before presenting anything to the user. Never show credentials without their subscribed APIs.
  • Never show raw IDs (licenseConfigId, credentialId, productId) to the user — use names instead.
  • Integrations and credentials are the same concept. The get_credentials response uses id_integration as the credential ID — use this value wherever credentialId is required in any tool call. integration_name is the credential's display name.
  • Never use internal jargon — present licenseConfigs as "product profiles" to the user.
  • Never skip product profile selection. If properties.licenseConfigs is non-empty for an API, always complete step 5 and include the selected licenseConfigs in the services array — both when subscribing to an existing credential and when creating a new one. An omitted or empty licenseConfigs means the subscription will have no product profile attached.
  • list_services returns a very large payload that exceeds the inline token limit. When you need to find an API code or inspect its details, search the saved file with a shell command (e.g. python3 -c "import json; ..." filtering by name/code) rather than reading the full response inline.
Repository

adobe/skills

Path

plugins/adobe-for-developers/skills/dev-console-subscribe-api/SKILL.md

Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.