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

# SetBusinessProfileAPI mirrors erdo_set_business_profile. PUT rather than


> POST: there is exactly one profile per organization and a save replaces it.

A guest is refused outright rather than left to the org-admin check below it: the profile is the organization's legal identity, and a shared-link visitor has no business writing one even in the impossible case that they hold a role.




## OpenAPI

````yaml /api/openapi.json put /v1/org/business-profile
openapi: 3.0.0
info:
  title: Erdo API
  description: >-
    Erdo's REST API: query and write datasets, run agents, manage threads,
    integrations, pages, evals, workstreams, experiments, and bounded outreach.
    Authenticate with a Bearer API key (erdo_api_...) or scoped token
    (erdo_token_...).
  version: '2026-09-09'
servers:
  - url: https://api.erdo.ai
    description: Production
security:
  - bearerAuth: []
paths:
  /v1/org/business-profile:
    put:
      summary: |
        SetBusinessProfileAPI mirrors erdo_set_business_profile. PUT rather than
      description: >
        POST: there is exactly one profile per organization and a save replaces
        it.


        A guest is refused outright rather than left to the org-admin check
        below it: the profile is the organization's legal identity, and a
        shared-link visitor has no business writing one even in the impossible
        case that they hold a role.
      operationId: PUT:mcp.SetBusinessProfileAPI
      requestBody:
        content:
          application/json:
            schema:
              properties:
                city:
                  type: string
                country:
                  type: string
                entity_type:
                  type: string
                industry:
                  type: string
                legal_name:
                  type: string
                legal_structure:
                  description: >
                    The entity's legal form, which the registry asks for
                    alongside — not instead of — the public/private status in
                    entity_type, and checks against the tax record. An LLC
                    declared as a corporation is a rejection days later rather
                    than an error at save time.
                  enum:
                    - sole_proprietorship
                    - partnership
                    - limited_liability_corporation
                    - co_operative
                    - non_profit_corporation
                    - corporation
                  title: >
                    LegalStructure is one of the accepted legal structures, and
                    required:
                  type: string
                postal_code:
                  type: string
                privacy_policy_url:
                  description: >
                    them is a campaign rejection after the vetting fee has been
                    taken.
                  title: >
                    The two policy pages every A2P campaign registration must
                    name. Omitting
                  type: string
                region:
                  type: string
                representative_email:
                  type: string
                representative_first_name:
                  type: string
                representative_job_position:
                  type: string
                representative_last_name:
                  type: string
                representative_phone:
                  type: string
                representative_title:
                  type: string
                stock_exchange:
                  description: >
                    public\_for\_profit and refused otherwise, because the
                    campaign registry asks a public brand for both and nobody
                    else has them.
                  title: |
                    A public company's listing. Required when entity_type is
                  type: string
                stock_ticker:
                  type: string
                street:
                  type: string
                tax_id:
                  type: string
                terms_and_conditions_url:
                  type: string
                website_url:
                  type: string
              type: object
      responses:
        '200':
          content:
            application/json:
              schema:
                properties:
                  entity_types:
                    description: >
                      the profile so a form (or an agent explaining the form)
                      never has to carry its own copy that drifts from the one
                      validation uses.
                    items:
                      type: string
                    title: >
                      EntityTypes, LegalStructures and Industries are the
                      accepted vocabularies,
                    type: array
                  exists:
                    description: >
                      the zero value rather than null, so a form binds to it
                      without a nil check.
                    title: >
                      Exists is false when the org has never saved a profile.
                      Profile is then
                    type: boolean
                  industries:
                    items:
                      type: string
                    type: array
                  job_positions:
                    items:
                      type: string
                    type: array
                  legal_structures:
                    description: >
                      The accepted legal structures, returned with the profile
                      so a form (or an agent explaining the form) never has to
                      carry its own copy that drifts from the one validation
                      uses.
                    items:
                      type: string
                    type: array
                  missing_fields:
                    description: >
                      form shows them. Empty means the profile is ready to
                      submit.
                    items:
                      type: string
                    title: >
                      MissingFields names the fields registration still needs,
                      in the order a
                    type: array
                  profile:
                    $ref: '#/components/schemas/organization.BusinessProfile'
                type: object
          description: Success response
        default:
          $ref: '#/components/responses/APIError'
components:
  schemas:
    organization.BusinessProfile:
      description: >
        except the tax id, plus the last four digits of it. There is
        deliberately no field carrying the number itself — a struct that could
        hold it is a struct that will eventually be logged.
      properties:
        city:
          type: string
        country:
          type: string
        entity_type:
          type: string
        industry:
          type: string
        legal_name:
          type: string
        legal_structure:
          description: >
            The entity's legal form, which the registry asks for alongside — not
            instead of — the public/private status in entity_type, and checks
            against the tax record. An LLC declared as a corporation is a
            rejection days later rather than an error at save time.
          enum:
            - sole_proprietorship
            - partnership
            - limited_liability_corporation
            - co_operative
            - non_profit_corporation
            - corporation
          title: |
            LegalStructure is the entity's legal form, asked for alongside — not
          type: string
        postal_code:
          type: string
        privacy_policy_url:
          description: >
            filed without them is rejected by vetting that has already been paid
            for.
          title: >
            The two policy pages the campaign registration has to name. A
            campaign
          type: string
        region:
          type: string
        representative_email:
          type: string
        representative_first_name:
          type: string
        representative_job_position:
          description: |
            free-text title. Twilio wants both.
          title: |
            RepresentativeJobPosition is the role from a fixed list, beside the
          type: string
        representative_last_name:
          type: string
        representative_phone:
          type: string
        representative_title:
          type: string
        stock_exchange:
          description: |
            everyone else. The registry asks a public brand for both.
          title: |
            StockExchange and StockTicker are a public company's, and empty for
          type: string
        stock_ticker:
          type: string
        street:
          type: string
        submitted_by_user_id:
          format: uuid
          type: string
        tax_id_last4:
          description: |
            legitimately has none.
          title: >
            TaxIDLast4 is empty when no tax id has been stored. A sole
            proprietor
          type: string
        tax_id_stored:
          description: >
            re-enter to change" rather than an empty box that looks unsaved.


            There is deliberately no version token here. The stored version
            exists so registration can tell a replaced EIN from an unchanged
            one, which is a question only the registration flow asks; a
            user-facing read that carried it would be publishing a per-org
            fingerprint of the number for no reason anybody on this surface has.
          title: >
            TaxIDStored says whether a tax id is on file, so a form can show
            "stored,
          type: boolean
        terms_and_conditions_url:
          type: string
        updated_at:
          type: string
        website_url:
          type: string
      title: |
        BusinessProfile is the profile as every read surface sees it: everything
      type: object
  responses:
    APIError:
      content:
        application/json:
          schema:
            externalDocs:
              url: https://pkg.go.dev/encore.dev/beta/errs#Error
            properties:
              code:
                description: Error code
                example: not_found
                externalDocs:
                  url: https://pkg.go.dev/encore.dev/beta/errs#ErrCode
                type: string
              details:
                description: Error details
                type: object
              message:
                description: Error message
                type: string
            title: APIError
            type: object
      description: Error response
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: An Erdo API key (erdo_api_...) or scoped token (erdo_token_...).

````