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

# Create a session

> Creates a session that unlocks one O.J. screen. Call it from your server, never from a browser. The response
contains a `client_token` for the O.J. Embed library, which works once and expires after fifteen minutes,
and a hosted `url` for partners that would rather redirect, which lasts `expires_in_seconds` (24 hours by
default).

`purpose` picks the screen:
- `status` shows the borrower's progress, to-dos, matches and offers.
- `intake` is the full application for a new business, prefilled from `prefill`, including the credit authorization. It creates the referral when the borrower submits.
- `documents` lets the borrower connect a bank or upload what O.J. still needs.
- `bank_connect` opens Plaid, for statements or the funding account. You never see balances or credentials.
- `offer_acceptance` lets the borrower compare offers, accept and sign, and choose the funding account.
- `conversation` shows the borrower's messages with O.J.

`theme` sets your logo and colours. The wording and legal disclosures on the screen are O.J.'s and cannot be
changed. When the borrower finishes on the hosted page, they are sent to your `return_url` with
`?referral_id=` added.




## OpenAPI

````yaml /api-reference/openapi.yaml post /partner_sessions
openapi: 3.1.0
info:
  title: O.J. Agent Development Kit (ADK)
  version: 0.5.1
  summary: >-
    Send O.J. a business. Get back named lender matches, what's needed, offers
    and funding status.
  description: >
    The O.J. ADK lets platforms with small-business customers offer financing
    without becoming a lender or a

    broker. You send a business as a **referral**. O.J. matches it to lender
    programs, collects documents,

    submits to lenders and tracks the deal to funding. You earn a share of the
    commission on every funded loan.


    Integrate with **O.J. Embed** (drop-in screens), the **REST API** with
    webhooks, or **MCP** for agents. All

    three read and write the same referral.


    Conventions: OAuth 2.0 client credentials, amounts in cents, prefixed ids,
    cursor pagination, an

    `Idempotency-Key` on every POST, RFC 9457 errors, and Standard Webhooks
    signatures.
  license:
    name: Proprietary — O.J. partner terms
    identifier: LicenseRef-OJ-Partner
  contact:
    name: O.J. Developer Support
    email: developers@meet-oj.com
servers:
  - url: https://sandbox.api.meet-oj.com/partner/v0
    description: Sandbox
  - url: https://api.meet-oj.com/partner/v0
    description: Production
security:
  - oauth2: []
tags:
  - name: Referrals
    description: >-
      A referral is one business you sent to O.J. Every other resource belongs
      to a referral.
  - name: Matches
    description: >-
      The lenders a business matches, named, with estimated limits. `POST
      /match_checks` screens raw numbers without creating a referral. A match is
      not a credit decision; the lender decides.
  - name: Documents
    description: >-
      Documents O.J. still needs, and uploads by API. Most integrations show the
      `next_action` button instead.
  - name: Offers
    description: >-
      Offers returned by lenders. Indicative terms computed before a lender
      replies are marked `binding: false`.
  - name: Sessions
    description: >-
      Create a session to open an O.J. screen: a `client_token` for Embed, or a
      hosted `url` to redirect to.
  - name: Events
    description: >-
      Every change to a referral is an event, delivered by webhook, streamed
      over SSE, and kept for 30 days at `GET /events`.
  - name: Payouts
    description: >-
      Your share of the commission on each funded referral. Match rows to your
      bank statement with `statement_descriptor`. Payout destinations are set
      during onboarding and cannot be changed by API.
  - name: Conversation
    description: >-
      The message thread between O.J., the borrower and your team on a referral,
      across every channel.
  - name: Channels
    description: >-
      Channel connectors let O.J. reach your borrowers through channels you own
      (in-app inbox, SMS, Apple Business Messages, email), in your brand.
  - name: Policy
    description: >-
      Account-level rules: send approval, allowed Embed origins, contact
      channels, default intent and reminder cadence.
  - name: Programs
    description: >-
      For lenders running a program on O.J.: receive submissions, record
      decisions and report funding.
  - name: Webhooks
    description: >-
      Register endpoints that receive signed events. Deliveries follow Standard
      Webhooks.
paths:
  /partner_sessions:
    post:
      tags:
        - Sessions
      summary: Create a session
      description: >
        Creates a session that unlocks one O.J. screen. Call it from your
        server, never from a browser. The response

        contains a `client_token` for the O.J. Embed library, which works once
        and expires after fifteen minutes,

        and a hosted `url` for partners that would rather redirect, which lasts
        `expires_in_seconds` (24 hours by

        default).


        `purpose` picks the screen:

        - `status` shows the borrower's progress, to-dos, matches and offers.

        - `intake` is the full application for a new business, prefilled from
        `prefill`, including the credit authorization. It creates the referral
        when the borrower submits.

        - `documents` lets the borrower connect a bank or upload what O.J. still
        needs.

        - `bank_connect` opens Plaid, for statements or the funding account. You
        never see balances or credentials.

        - `offer_acceptance` lets the borrower compare offers, accept and sign,
        and choose the funding account.

        - `conversation` shows the borrower's messages with O.J.


        `theme` sets your logo and colours. The wording and legal disclosures on
        the screen are O.J.'s and cannot be

        changed. When the borrower finishes on the hosted page, they are sent to
        your `return_url` with

        `?referral_id=` added.
      operationId: createPartnerSession
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerSessionCreate'
      responses:
        '201':
          description: Session created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSession'
        '400':
          $ref: '#/components/responses/Error'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: >
        IETF `Idempotency-Key` semantics
        (draft-ietf-httpapi-idempotency-key-header). Send a fresh unique value

        (a UUID) with every new request. A retry with the same key and the same
        payload returns the original

        response with the header `Idempotent-Replayed: true`. The same key with
        a different payload is rejected with

        422 and code `idempotency_key_reused`. Keys are kept for 24 hours.
      schema:
        type: string
        maxLength: 255
  schemas:
    PartnerSessionCreate:
      type: object
      description: >
        What you send to create a partner session. A session unlocks one O.J.
        screen, either as an Embed component

        inside your page or as a hosted page. `purpose` picks the screen.


        For a new business, use `intake` and put whatever you already know in
        `prefill`, so the borrower confirms it

        instead of typing it again. For an existing referral, pass its
        `referral_id`. `theme` sets your logo and

        colour. The wording and legal disclosures on the screen are O.J.'s and
        cannot be changed.
      required:
        - purpose
        - return_url
      properties:
        purpose:
          type: string
          enum:
            - status
            - conversation
            - intake
            - documents
            - bank_connect
            - offer_acceptance
          description: >-
            Which component (or hosted page) this session unlocks. See `x-embed`
            for what each one shows.
        referral_id:
          type: string
          description: Required for every purpose except intake.
        options:
          type: object
          description: >-
            Per-component options listed in `x-embed` (for example `compact` for
            the status card, `skip_known_fields` for intake,
            `document_request_ids` for documents).
          additionalProperties: true
        prefill:
          $ref: '#/components/schemas/ReferralCreate'
          description: >-
            For `intake` — anything already known; the borrower confirms rather
            than retypes.
        return_url:
          type: string
          format: uri
        expires_in_seconds:
          type: integer
          minimum: 300
          maximum: 604800
          default: 86400
        theme:
          type: object
          description: >-
            Partner colors and logo. O.J.'s copy and disclosures are not
            editable.
          properties:
            primary_color:
              type: string
              pattern: ^#[0-9A-Fa-f]{6}$
            logo_url:
              type: string
              format: uri
            partner_display_name:
              type: string
              description: How O.J. names the partner on the page ("Marisol asked me to…").
            radius:
              type: string
              enum:
                - sharp
                - rounded
            mode:
              type: string
              enum:
                - light
                - dark
                - auto
            locale:
              type: string
              enum:
                - en
    PartnerSession:
      type: object
      description: >-
        A minted hosted-page link. Send the borrower to `url` by redirect, new
        tab, text message, or QR code. When they finish, they are returned to
        your `return_url` with `?referral_id=` appended.
      required:
        - id
        - url
        - expires_at
      properties:
        id:
          type: string
          examples:
            - ps_01K5X3T5E9
        object:
          type: string
          const: partner_session
        url:
          type: string
          format: uri
          description: Redirect, open in a new tab, or render as a QR code.
        client_token:
          type: string
          description: >-
            Hand this to the browser for O.J. Embed (`OJ.create({ token })`).
            Single use, 15 minutes, bound to this session's purpose and
            referral. Never expose your client credentials to a browser; this
            token is what goes there instead.
        referral_id:
          type: string
        expires_at:
          type: string
          format: date-time
    ReferralCreate:
      type: object
      description: >
        The body you send to create a referral. Five things are required: your
        own id for the business

        (`external_id`), who will talk to the borrower (`intent`), the business,
        at least one contact, and a consent

        record. Everything else is optional and makes the first matches more
        complete.
      required:
        - external_id
        - intent
        - business
        - contacts
        - consent
      properties:
        external_id:
          type: string
          description: Your customer, merchant, or listing id. Unique per partner.
        intent:
          $ref: '#/components/schemas/Intent'
        product_hint:
          $ref: '#/components/schemas/Product'
        requested_amount:
          $ref: '#/components/schemas/Money'
        use_of_funds:
          type: string
          enum:
            - working_capital
            - inventory
            - equipment
            - expansion
            - acquisition
            - refinance
            - payroll
            - real_estate
            - other
        business:
          $ref: '#/components/schemas/Business'
        contacts:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/Contact'
        context:
          $ref: '#/components/schemas/Context'
        consent:
          $ref: '#/components/schemas/Consent'
        source:
          type: object
          description: >-
            Attribution below the partner — a sub-partner, agent, or campaign.
            Drives overrides.
          properties:
            sub_partner_id:
              type: string
            campaign:
              type: string
        metadata:
          type: object
          additionalProperties:
            type: string
          maxProperties: 20
    Error:
      type: object
      description: >
        RFC 9457 Problem Details, returned as `application/problem+json` with
        any 4xx or 5xx status. `type` is a

        URI that identifies the kind of problem and doubles as a link to its
        documentation; `title` is the short

        human name for that kind; `status` repeats the HTTP status; `detail`
        explains this occurrence for a

        developer; `instance` is the request path. Three extension members:
        `code`, a stable snake_case reason to

        branch on; `param`, the offending field when the request was invalid;
        `request_id`, to quote to support.

        One code deserves a note: `awaiting_approval` (HTTP 409) is not a
        failure. It means the action you asked

        for needs a person at your company to confirm it first, and the referral
        shows `needs_partner` until they do.
      required:
        - type
        - title
        - status
        - code
        - request_id
      properties:
        type:
          type: string
          format: uri
          examples:
            - https://api.meet-oj.com/problems/duplicate-external-id
        title:
          type: string
          examples:
            - Referral already exists
        status:
          type: integer
          examples:
            - 409
        detail:
          type: string
          examples:
            - >-
              A referral with external_id cust_8842 was created on 2026-09-20 as
              ref_01K5X3K7Q2.
        instance:
          type: string
          examples:
            - /partner/v0/referrals
        code:
          type: string
          description: >-
            Stable machine-readable reason. Categories are the prefixes;
            specific codes follow.
          examples:
            - invalid_request
            - authentication_failed
            - permission_denied
            - not_found
            - duplicate_external_id
            - business_already_referred
            - missing_consent
            - required_documents_missing
            - idempotency_key_reused
            - rate_limited
            - awaiting_approval
            - internal_error
        param:
          type: string
          description: The field that caused an invalid_request, in dot notation.
        request_id:
          type: string
          examples:
            - req_01K5X4A9M2
    Intent:
      type: string
      description: >
        Who the borrower hears from. O.J. does the work either way. With
        `just_refer`, O.J. contacts the borrower

        directly, introducing itself as working with you, and sends the borrower
        the link for each to-do. With

        `work_this_deal`, O.J. never contacts the borrower; each to-do arrives
        in the referral's `todos` with a link

        you place in your own product, so the borrower acts inside your flow.
      enum:
        - work_this_deal
        - just_refer
    Product:
      type: string
      description: >
        A kind of financing. When you pass one as `product_hint`, O.J. still
        checks every product it can place, but

        lists the hinted one first. `revenue_based_financing` is repaid as a
        share of sales; `term_loan` is a fixed

        amount repaid over a fixed period; `business_line_of_credit` can be
        drawn and repaid repeatedly; `sba_7a` is a

        government-guaranteed bank loan; `invoice_factoring` advances money
        against unpaid invoices;

        `asset_based_lending` is secured by inventory or equipment;
        `hard_money_lending` is secured by real estate.
      enum:
        - revenue_based_financing
        - term_loan
        - business_line_of_credit
        - sba_7a
        - invoice_factoring
        - asset_based_lending
        - hard_money_lending
    Money:
      type: integer
      description: >-
        A dollar amount expressed in whole US cents, so $85,000.00 is `8500000`.
        Cents avoid rounding errors that decimals cause in some languages.
    Business:
      type: object
      description: >
        The company that needs financing. Only the legal name and address are
        required to create a referral;

        everything else improves matching. The EIN (federal tax ID) is used to
        detect the same business arriving from two

        partners, in which case the first partner keeps the referral. The NAICS
        code (a six-digit industry

        classification) or a free-text `industry` lets programs with industry
        restrictions evaluate correctly.
      required:
        - legal_name
        - address
      properties:
        legal_name:
          type: string
          description: The registered name of the company.
        dba:
          type: string
          description: Trading name, if different from the legal name (doing business as).
        ein:
          type: string
          pattern: ^[0-9]{2}-[0-9]{7}$
          description: >-
            Used to dedupe across partners (first-referrer rule). Not needed for
            `match_checks`.
        entity_type:
          type: string
          enum:
            - sole_prop
            - llc
            - s_corp
            - c_corp
            - partnership
            - nonprofit
        formation_date:
          type: string
          format: date
        naics:
          type: string
          pattern: ^[0-9]{6}$
        industry:
          type: string
          description: Free text when NAICS is unknown.
        address:
          $ref: '#/components/schemas/Address'
        phone:
          type: string
        website:
          type: string
          format: uri
        stated_annual_revenue:
          $ref: '#/components/schemas/Money'
          description: >-
            As stated by the business or partner. Corroborated against
            statements before submission.
        number_of_workers:
          type: integer
          minimum: 0
    Contact:
      type: object
      description: >
        A person at the business. At least one contact is required, and one
        should be marked `is_primary` — that is

        who O.J. or the partner will talk to. Lenders also want to know every
        owner with a 20% or larger stake, so

        list them with `ownership_pct`. Never send Social Security numbers: O.J.
        collects them on its own screen

        when the owner authorizes the credit check. If the owner has told you
        their score range, or you hold it in

        your own records, send `credit_band` and O.J. uses it for early matches
        until the check completes. Never send a

        score you pulled from a credit bureau.
      required:
        - first_name
        - last_name
      properties:
        first_name:
          type: string
        last_name:
          type: string
        title:
          type: string
        email:
          type: string
          format: email
        phone:
          type: string
        ownership_pct:
          type: number
          minimum: 0
          maximum: 100
        credit_band:
          type: string
          enum:
            - under_600
            - 600_659
            - 660_699
            - 700_plus
            - unknown
        is_primary:
          type: boolean
    Context:
      type: object
      description: >
        Everything you already know about the business, in whatever combination
        you have. The more you send, the more

        of the matching O.J. can do immediately, before any documents arrive.
        Figures you report are later checked

        against the borrower's bank data; if they disagree by more than a small
        tolerance, an O.J. reviewer looks at

        the file before it goes to lenders.
      properties:
        ledger:
          type: array
          maxItems: 24
          items:
            $ref: '#/components/schemas/LedgerMonth'
        listing:
          $ref: '#/components/schemas/Listing'
        bank_connection:
          type: object
          description: >-
            A Plaid processor token issued for O.J. It replaces bank statements.
            If the Item includes Auth, the borrower can also choose it as the
            funding account later without connecting again.
          required:
            - provider
            - token
          properties:
            provider:
              type: string
              enum:
                - plaid
            token:
              type: string
              writeOnly: true
        relationship:
          type: object
          properties:
            customer_since:
              type: string
              format: date
            products_used:
              type: array
              items:
                type: string
            monthly_processing_volume:
              $ref: '#/components/schemas/Money'
        notes:
          type: string
          maxLength: 2000
          description: >-
            Free text from the partner. Becomes the first line of the deal
            thread.
    Consent:
      type: object
      description: >
        A record of what the business agreed to before you sent it to O.J. At
        minimum, the business must have agreed

        that you may share its information with O.J. and O.J.'s lenders. If you
        use `intent: just_refer`, the business

        must also have agreed that O.J. may contact it. Anything you did not
        capture, O.J. captures on its own hosted

        pages before proceeding.
      required:
        - shared_with_oj_at
      properties:
        shared_with_oj_at:
          type: string
          format: date-time
          description: >-
            The business agreed that the partner may share its information with
            O.J. and O.J.'s lenders.
        contact_authorized_at:
          type: string
          format: date-time
          description: >-
            Required for `just_refer` — the business agreed O.J. may contact it
            (TCPA).
        terms_version:
          type: string
        ip_address:
          type: string
    Address:
      type: object
      description: >-
        A US postal address. `state` is the two-letter abbreviation. The state
        matters more than it looks; several lender programs only operate in
        certain states, and some states have their own disclosure rules.
      required:
        - line1
        - city
        - state
        - postal_code
      properties:
        line1:
          type: string
        line2:
          type: string
        city:
          type: string
        state:
          type: string
          pattern: ^[A-Z]{2}$
        postal_code:
          type: string
    LedgerMonth:
      type: object
      description: >
        One month of money in and out of the business, as recorded by a system
        you already run: a bank account, a

        bill-pay product, or a card-processing account. Send as many months as
        you have, up to 24. For a processor,

        put card settlements in `sales_deposits`. `nsf_count` is the number of
        times a payment bounced for

        insufficient funds that month, which almost every lender program checks.
      required:
        - month
      properties:
        month:
          type: string
          pattern: ^[0-9]{4}-[0-9]{2}$
        sales_deposits:
          $ref: '#/components/schemas/Money'
        total_inflows:
          $ref: '#/components/schemas/Money'
        total_outflows:
          $ref: '#/components/schemas/Money'
        average_daily_balance:
          $ref: '#/components/schemas/Money'
        ending_balance:
          $ref: '#/components/schemas/Money'
        nsf_count:
          type: integer
          minimum: 0
        chargeback_count:
          type: integer
          minimum: 0
          description: Processors only.
        transaction_count:
          type: integer
          minimum: 0
    Listing:
      type: object
      description: >
        For platforms that list businesses for sale. It carries what a listing
        already knows about the company being

        bought, which is most of what an SBA acquisition loan needs.
        `sde_trailing_12` is seller's discretionary

        earnings over the last twelve months (profit before the owner's pay and
        one-off expenses).

        `buyer_equity_injection_pct` is the share of the price the buyer is
        putting in as cash. These feed the SBA

        acquisition rules that took effect on October 1, 2026 (SOP 50 10 8.1):
        debt-service coverage of at least 1.25

        on historical earnings, a 10% injection with limits on where it can come
        from, and a mandatory quality-of-

        earnings review when the price is $3M or more.
      properties:
        listing_id:
          type: string
          description: Your listing id.
        asking_price:
          $ref: '#/components/schemas/Money'
        sde_trailing_12:
          $ref: '#/components/schemas/Money'
        ebitda_trailing_12:
          $ref: '#/components/schemas/Money'
        revenue_trailing_12:
          $ref: '#/components/schemas/Money'
        includes_real_estate:
          type: boolean
        real_estate_value:
          $ref: '#/components/schemas/Money'
        buyer_equity_injection_pct:
          type: number
          minimum: 0
          maximum: 100
        seller_note_pct:
          type: number
          minimum: 0
          maximum: 100
        buyer_industry_experience_years:
          type: integer
          minimum: 0
        financials_available:
          type: array
          items:
            $ref: '#/components/schemas/DocumentType'
    DocumentType:
      type: string
      description: >-
        The kinds of documents O.J. can request or accept. `cim` is a
        confidential information memorandum, the summary document a business
        broker prepares for a sale. `quality_of_earnings` is an accountant's
        review of reported earnings, required by the SBA for acquisitions of $3M
        or more. `funding_account_auth` is the funding account verified through
        Plaid; `voided_check` is the fallback when the bank can't be verified.
      enum:
        - bank_statement
        - processing_statement
        - voided_check
        - funding_account_auth
        - tax_return
        - profit_and_loss
        - balance_sheet
        - ar_aging
        - ap_aging
        - debt_schedule
        - business_license
        - government_id
        - lease
        - ownership_document
        - cim
        - purchase_agreement
        - quality_of_earnings
        - other
  responses:
    Error:
      description: Problem Details (RFC 9457)
      headers:
        OJ-Request-Id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Error'
  headers:
    RequestId:
      description: >-
        Unique id for this request. Quote it to support; it is also in Problem
        Details as `request_id` and in O.J.'s traces.
      schema:
        type: string
        examples:
          - req_01K5X4A9M2
  securitySchemes:
    oauth2:
      type: oauth2
      description: >-
        One client per partner per environment. Access tokens expire after 15
        minutes. Scopes are granted per client. Sandbox clients use
        https://sandbox.api.meet-oj.com/oauth/token.
      flows:
        clientCredentials:
          tokenUrl: https://api.meet-oj.com/oauth/token
          scopes:
            referrals:write: Create referrals and upload documents
            referrals:read: Read referrals, matches, document requests, offers, events
            match_checks:write: Run identity-free match checks
            sessions:write: Mint hosted-session links
            webhooks:manage: Register and list webhook endpoints
            payouts:read: >-
              Read payouts (your statement). There is no payouts:write;
              destinations are managed in hosted onboarding by a person.
            messages:read: Read a referral's conversation
            messages:write: >-
              Send messages into a referral's conversation on behalf of the
              partner or the borrower
            channels:manage: Register and remove channel connectors
            policy:manage: Read and change the partner policy
            submissions:read: >-
              For banks running a program. List and read submissions awaiting
              review
            submissions:write: For banks running a program. Record decisions and report funding

````