> ## Documentation Index
> Fetch the complete documentation index at: https://rubie.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Create embedded credential session

> Start an origin-bound Blueprint picker and credential capture flow.

Creates a short-lived iframe URL for the Rubie Embedded Credential Capture
widget. Create the session from your backend, return `embed_url` to the browser,
and mount it in an iframe on `parent_origin`.

```bash theme={null}
curl --fail-with-body -sS \
  "$RUBIE_API_URL/api/v1/embedded-credential-sessions" \
  -X POST \
  -H "Authorization: Bearer $RUBIE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: connect-user-123" \
  -d '{
    "blueprint_keys": ["adp-worker-sync", "gusto-worker-sync"],
    "parent_origin": "https://app.example.com",
    "name": "Acme Corp HR connection"
  }'
```

## Notes

* `blueprint_keys` is the exact set of Blueprints the user may select. Passing
  one key skips the picker.
* `parent_origin` must be an allowlisted HTTPS origin with no path, query, or
  fragment.
* Sessions expire after 15 minutes. Create one when the user opens the flow.
* Use one idempotency key per deliberate opening. Reusing a key can replay an
  expired session.
* Blueprint branding and its primary authentication strategy are configured in
  Rubie.

See [Embedded Credential Capture](/guides/embedded-credential-capture) for iframe
mounting, browser events, and server-side confirmation.


## OpenAPI

````yaml POST /embedded-credential-sessions
openapi: 3.0.3
info:
  title: Rubie API
  version: 1.0.0
  description: >
    Collect end-user credentials through a Rubie-hosted form, then run Rubie

    Blueprints against them asynchronously.


    This API is deliberately thin. Rubie does not model your domain: what a

    Blueprint accepts as input, what it does with a connected system, and what
    it

    produces are all defined by that Blueprint's configuration. The endpoints

    below are the transport around it.


    All endpoints require bearer authentication. Responses use opaque prefixed
    IDs

    (`cred_`, `sess_`, `ecs_`, `strat_`, `run_`, `bp_`), snake_case fields, and
    a

    single top-level error envelope — never a `success` wrapper.
servers:
  - url: https://app.rubiehq.com/api/v1
    description: Production
security:
  - BearerAuth: []
tags:
  - name: Credential Sessions
    description: Start and poll Rubie-hosted credential collection flows.
  - name: Embedded Credential Sessions
    description: Embed a Blueprint picker and credential capture flow in your product.
  - name: Credentials
    description: Revoke vaulted credentials.
  - name: Blueprints
    description: Trigger a Rubie Blueprint run.
  - name: Blueprint Runs
    description: Poll run status and retrieve completed outputs.
paths:
  /embedded-credential-sessions:
    post:
      tags:
        - Embedded Credential Sessions
      summary: Create an embedded credential session
      description: >
        Creates a short-lived, origin-bound iframe URL for the Rubie Embedded
        Credential Capture widget. The widget shows only the supplied
        Blueprints, then captures credentials for the Blueprint selected by the
        end user. Create this session from your backend; API keys must never be
        sent to the browser.
      operationId: createEmbeddedCredentialSession
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateEmbeddedCredentialSessionRequest'
      responses:
        '201':
          description: Embedded credential session created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmbeddedCredentialSession'
              example:
                id: ecs_MQ
                status: pending
                embed_url: https://app.rubiehq.com/embed/credential-capture/abc123
                blueprint_keys:
                  - adp-worker-sync
                  - gusto-worker-sync
                  - bamboohr-worker-sync
                selected_blueprint_key: null
                credential_id: null
                parent_origin: https://app.example.com
                expires_at: '2026-08-17T23:00:00.000Z'
                completed_at: null
                created_at: '2026-08-17T22:45:00.000Z'
        '400':
          $ref: '#/components/responses/ValidationError'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/ValidationError'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
      description: >
        Unique key for safely retrying mutating requests. Matching key + body
        replays the original response for 24 hours. Matching key + different
        body returns 409 conflict.
  schemas:
    CreateEmbeddedCredentialSessionRequest:
      type: object
      required:
        - blueprint_keys
        - parent_origin
      properties:
        blueprint_keys:
          type: array
          minItems: 1
          maxItems: 50
          uniqueItems: true
          items:
            type: string
          description: >
            Blueprint keys the end user may select. Passing one key skips the
            picker and opens that Blueprint's credential form directly.
          example:
            - adp-worker-sync
            - gusto-worker-sync
            - bamboohr-worker-sync
        parent_origin:
          type: string
          format: uri
          maxLength: 2048
          example: https://app.example.com
          description: >
            Exact HTTPS origin where the iframe will be mounted. It must be
            allowlisted for the account and contain no path, query, or fragment.
        name:
          type: string
          maxLength: 256
          description: Optional display name for the connection in the Rubie dashboard.
      example:
        blueprint_keys:
          - adp-worker-sync
          - gusto-worker-sync
          - bamboohr-worker-sync
        parent_origin: https://app.example.com
        name: Acme Corp HR connection
    EmbeddedCredentialSession:
      type: object
      required:
        - id
        - status
        - blueprint_keys
        - parent_origin
        - expires_at
        - created_at
      properties:
        id:
          type: string
          example: ecs_MQ
          description: Opaque embedded credential session id.
        status:
          $ref: '#/components/schemas/EmbeddedCredentialSessionStatus'
        embed_url:
          type: string
          format: uri
          nullable: true
          description: >
            Origin-bound iframe URL. Present while the session is pending and
            null after it completes or expires.
        blueprint_keys:
          type: array
          minItems: 1
          maxItems: 50
          uniqueItems: true
          items:
            type: string
          description: Exact set of Blueprints displayed in the widget.
        selected_blueprint_key:
          type: string
          nullable: true
          description: >
            Blueprint selected by the end user. Present when status is completed
            and guaranteed to belong to blueprint_keys.
        credential_id:
          type: string
          nullable: true
          example: cred_NDc
          description: >
            Vaulted credential id. Present only when status is completed. Retain
            it against the initiating user and selected Blueprint.
        parent_origin:
          type: string
          format: uri
          example: https://app.example.com
          description: Exact allowlisted HTTPS origin permitted to frame the widget.
        expires_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time
    EmbeddedCredentialSessionStatus:
      type: string
      description: >
        Lifecycle status of an embedded credential session. `completed` and
        `expired` are terminal. Treat this as an open string set and keep
        polling on statuses you do not recognise.
      enum:
        - pending
        - completed
        - expired
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/Error'
    Error:
      type: object
      required:
        - type
        - message
      properties:
        type:
          type: string
          enum:
            - authentication_error
            - authorization_error
            - not_found
            - validation_error
            - conflict
            - rate_limit_exceeded
            - internal_error
        message:
          type: string
        details:
          type: array
          items:
            $ref: '#/components/schemas/ErrorDetail'
    ErrorDetail:
      type: object
      required:
        - message
      properties:
        message:
          type: string
        code:
          type: string
          nullable: true
        field:
          type: string
          nullable: true
  responses:
    ValidationError:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: API key is not authorized for this resource
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    NotFound:
      description: Resource not found in this account
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Conflict:
      description: Request conflicts with the current resource state
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: APIKey
      description: Your Rubie API key as a bearer token.

````