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

# Resolve a social oEmbed

> Resolve public social posts into normalized metadata and available embed markup.

Send a Pirehub API key with `oembed:read` in `x-pirehub-api-key` or as a bearer
token. OAuth tokens require the same scope. See [Authentication](/api-reference/authentication).

The JSON body accepts only `url`. Supported providers are X, Facebook, Instagram,
Threads, TikTok, and Reddit. Response fields may be null when unavailable.
X currently returns metadata with `embed.html: null` and `embed.scripts: []`.

Treat provider HTML as untrusted and render it in an isolated, sandboxed iframe.
Use `capabilities` to determine which rendering options are available.

See the [oEmbed guide](/guides/oembed) for authentication, response examples,
provider URL formats, caching, and errors.


## OpenAPI

````yaml api-reference/openapi.json POST /api/v1/oembed/resolve
openapi: 3.1.0
info:
  title: Pirehub by ntanduy API
  description: >-
    Scoped developer APIs from ntanduy for domain and IP intelligence, secured
    media processing, and Vietnamese bank QR utilities.
  version: 1.0.0
servers:
  - url: https://www.ntanduy.com
    description: Production
security: []
tags:
  - name: Screenshot tools
    description: Capture public webpages as PNG images.
  - name: Social embeds
    description: Resolve public social URLs into normalized oEmbed data.
  - name: Domains
    description: Domain registration, WHOIS, and DNS resolution intelligence.
  - name: IP information
    description: >-
      Normalized location, network, and timezone information for public IP
      addresses.
  - name: Video tools
    description: Video metadata and secure download-option extraction.
  - name: Payment utilities
    description: Scoped APIs for generating interoperable bank-transfer artifacts.
  - name: Free subdomains
    description: >-
      First-party dashboard routes requiring a Clerk session and automatic
      website verification for namespace registration, desired DNS state,
      asynchronous provider operations, and DNS propagation verification.
paths:
  /api/v1/oembed/resolve:
    post:
      tags:
        - Social embeds
      summary: Resolve a social oEmbed
      description: >-
        Resolve public X, Facebook, Instagram, Threads, TikTok, or Reddit
        content with oembed:read. The body accepts only url. Results may be
        cached for one hour; cache hits still count toward API-key quotas. X
        returns metadata without embed HTML or scripts. Other providers may
        return third-party HTML and scripts; render them in an isolated,
        sandboxed iframe. Provider-specific metadata is omitted.
      operationId: resolveOEmbed
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - url
              additionalProperties: false
              properties:
                url:
                  type: string
                  format: uri
                  maxLength: 2048
                  minLength: 1
                  description: >-
                    Public provider post URL. Trimmed, normalized to HTTPS, and
                    checked against allowed hosts and public network
                    destinations. Replace the example placeholders with a real
                    post.
            example:
              url: https://x.com/USERNAME/status/POST_ID
      responses:
        '200':
          description: >-
            Normalized oEmbed data in the standard success envelope;
            provider-specific metadata is omitted.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                type: object
                required:
                  - success
                  - data
                properties:
                  success:
                    const: true
                  data:
                    type: object
                    required:
                      - provider
                      - type
                      - originalUrl
                      - resolvedUrl
                      - title
                      - author
                      - providerInfo
                      - thumbnail
                      - embed
                      - capabilities
                    properties:
                      provider:
                        type: string
                        enum:
                          - x
                          - facebook
                          - instagram
                          - threads
                          - tiktok
                          - reddit
                      type:
                        type: string
                        enum:
                          - rich
                          - video
                          - photo
                          - link
                      originalUrl:
                        type: string
                        format: uri
                        description: >-
                          Input after initial URL normalization (HTTPS and
                          fragment removal).
                      resolvedUrl:
                        type: string
                        format: uri
                        description: Provider URL after redirects and canonicalization.
                      title:
                        type:
                          - string
                          - 'null'
                      author:
                        type: object
                        required:
                          - name
                          - url
                        properties:
                          name:
                            type:
                              - string
                              - 'null'
                          url:
                            type:
                              - string
                              - 'null'
                            format: uri
                      providerInfo:
                        type: object
                        required:
                          - name
                          - url
                        properties:
                          name:
                            type: string
                          url:
                            type:
                              - string
                              - 'null'
                            format: uri
                      thumbnail:
                        type:
                          - object
                          - 'null'
                        required:
                          - url
                          - width
                          - height
                        properties:
                          url:
                            type: string
                            format: uri
                          width:
                            type:
                              - number
                              - 'null'
                            minimum: 0
                          height:
                            type:
                              - number
                              - 'null'
                            minimum: 0
                      embed:
                        type: object
                        required:
                          - html
                          - width
                          - height
                          - scripts
                        properties:
                          html:
                            type:
                              - string
                              - 'null'
                            description: >-
                              Third-party markup. Render only in an isolated,
                              sandboxed iframe. Null for X.
                          width:
                            type:
                              - number
                              - 'null'
                            minimum: 0
                          height:
                            type:
                              - number
                              - 'null'
                            minimum: 0
                          scripts:
                            type: array
                            items:
                              type: object
                              required:
                                - src
                              properties:
                                src:
                                  type: string
                                  format: uri
                                async:
                                  type: boolean
                                defer:
                                  type: boolean
                      capabilities:
                        type: object
                        required:
                          - html
                          - thumbnail
                          - nativeEmbed
                          - requiresHydration
                        properties:
                          html:
                            type: boolean
                            description: Embed HTML is available.
                          thumbnail:
                            type: boolean
                            description: A thumbnail is available.
                          nativeEmbed:
                            type: boolean
                            description: Provider-native embedding is available.
                          requiresHydration:
                            type: boolean
                            description: Provider scripts must run to complete the embed.
              example:
                success: true
                data:
                  provider: x
                  type: rich
                  originalUrl: https://x.com/USERNAME/status/123456789
                  resolvedUrl: https://x.com/i/status/123456789
                  title: Example public post text.
                  author:
                    name: Example author
                    url: https://x.com/USERNAME
                  providerInfo:
                    name: X
                    url: https://x.com
                  thumbnail: null
                  embed:
                    html: null
                    width: null
                    height: null
                    scripts: []
                  capabilities:
                    html: false
                    thumbnail: false
                    nativeEmbed: false
                    requiresHydration: false
        '400':
          description: >-
            VALIDATION_ERROR for malformed body or extra fields;
            OEMBED_INVALID_URL or OEMBED_SECURITY_REJECTED for invalid or unsafe
            URLs.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: UNAUTHORIZED for invalid API credentials.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: >-
            FORBIDDEN for revoked, expired, or insufficiently scoped
            credentials; OEMBED_PRIVATE_CONTENT when the provider denies access.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: OEMBED_NOT_FOUND when the post is unavailable or removed.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            OEMBED_UNSUPPORTED_PROVIDER, OEMBED_UNSUPPORTED_URL, or
            OEMBED_URL_UNRESOLVED for unsupported content or unresolved short
            links.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: >-
            RATE_LIMITED or MONTHLY_QUOTA_EXCEEDED for API limits;
            OEMBED_RATE_LIMITED for provider throttling.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '502':
          description: >-
            OEMBED_UPSTREAM_ERROR or OEMBED_INVALID_RESPONSE for provider
            failures or unusable responses.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '504':
          description: OEMBED_UPSTREAM_TIMEOUT when a provider request times out.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
        - pirehubOAuth:
            - oembed:read
        - pirehubApiKey: []
        - bearerApiKey: []
components:
  headers:
    RequestId:
      description: >-
        Opaque correlation ID for this request. It matches `data.requestId` on
        JSON error responses.
      schema:
        type: string
        minLength: 1
        maxLength: 128
        pattern: ^[A-Za-z0-9._:-]+$
  schemas:
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
        - success
        - error
        - data
      properties:
        success:
          type: boolean
          const: false
        error:
          $ref: '#/components/schemas/ErrorDetail'
        data:
          $ref: '#/components/schemas/ErrorData'
    ErrorDetail:
      type: object
      additionalProperties: false
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Stable machine-readable error code.
        message:
          type: string
          description: Safe human-readable explanation.
    ErrorData:
      type: object
      description: >-
        Safe structured error metadata. Every JSON API error includes a
        correlation ID for support and log lookup.
      additionalProperties: true
      required:
        - requestId
      properties:
        requestId:
          type: string
          minLength: 1
          maxLength: 128
          pattern: ^[A-Za-z0-9._:-]+$
          description: >-
            Opaque correlation ID for this request. Include it when contacting
            support.
          example: 1704b073-5bf1-4d64-8f9a-3af95edb3bf1
  securitySchemes:
    pirehubOAuth:
      type: oauth2
      description: >-
        OAuth 2.0 Authorization Code with PKCE, issued by Pirehub's Clerk
        authorization server. Request only the scopes required by the operation.
      flows:
        authorizationCode:
          authorizationUrl: https://clerk.ntanduy.com/oauth/authorize
          tokenUrl: https://clerk.ntanduy.com/oauth/token
          refreshUrl: https://clerk.ntanduy.com/oauth/token
          scopes:
            domain:whois: Read normalized public WHOIS data.
            domain:dns: Read DNS records for a hostname.
            ip:lookup: Read allowlisted public IP information.
            video:extract: Read normalized metadata for a public video URL.
            screenshot:capture: Capture a public webpage as a PNG image.
            oembed:read: Resolve a public social URL to oEmbed data.
            bank-qr:generate: Generate a Vietnamese bank transfer QR payload and SVG.
            bank-qr:banks: Read the supported bank QR institution directory.
    pirehubApiKey:
      type: apiKey
      in: header
      name: x-pirehub-api-key
      description: A scoped Pirehub API key. Each operation documents its required scope.
    bearerApiKey:
      type: http
      scheme: bearer
      bearerFormat: Pirehub API key
      description: A Pirehub API key beginning with `ph_live_`.

````