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

# Create report request

> Creates a roof measurement report from a property address and starts the RoofKit AI measurement. The answer is 202 at once. A report takes about 15 minutes. Poll the request, or subscribe a workspace webhook endpoint to `report_request.ready`, then read the measurements, the PDF and the 3D model. A create with the `external_report_id` of a live request returns that request with 200 and starts no new report. When that request is ready and its 3D model failed or is missing, the create makes the model again, at most three times. The workspace pays the report as the app does.


**Required scopes:** `reports.write`


## OpenAPI

````yaml /api-reference/openapi.yaml post /api/v1/report-requests
openapi: 3.1.0
info:
  title: RoofKit Partner API
  version: 1.0.0
  summary: REST JSON API for external RoofKit partner integrations.
  contact:
    name: RoofKit Engineering
  description: >
    RoofKit Partner API v1 authenticates requests with workspace API keys. API
    keys bind each request to exactly one workspace; Partner API paths do not
    accept roofer_id, workspace_id, or tenant identifiers. Authenticated
    endpoints are limited to 60 requests per minute per API key, method, and
    route template; invalid authentication attempts are limited separately at 20
    requests per minute per client and endpoint. Date-time parameters and fields
    accept ISO 8601 with Z or a ±HH:MM offset, for example 2026-09-07T04:00:00Z
    or 2026-09-07T00:00:00-04:00. Both name the same instant and return the same
    result. Encode + as %2B in a query string. Responses return UTC.


    A date-time without an offset, for example 2026-09-07T04:00:00, is
    deprecated. Until the sunset on 2027-01-10T00:00:00Z it is read as UTC, and
    the response carries a `Deprecation` header (RFC 9745) and a `Sunset` header
    (RFC 8594). From the sunset, Z or a ±HH:MM offset is required. A date-time
    without an offset then returns 400 with the `VALIDATION_ERROR` code, and the
    response carries no `Deprecation` or `Sunset` header.


    Each API key holds only the scopes that a workspace owner or admin chose
    when the key was created, and its scopes never change. Each operation lists
    the scopes it requires in `x-required-scopes`. A new key in Settings starts
    on the Read-only preset: `leads.read`, `analytics.read`, `reports.read`, and
    `data_objects.read`. A Read-only key can call every read operation except
    exports, Sales Visualizer reads, and trashed Data Objects, and it cannot
    call any write operation. A call that needs a scope the key does not hold
    returns 403 `FORBIDDEN`, and `error.details.required_scope` names a missing
    scope.
servers:
  - url: https://api.roofkit.ai
    description: Canonical RoofKit Partner API origin
security:
  - ApiKeyBearer: []
tags:
  - name: Foundation
    description: Authentication and contract foundation endpoints.
  - name: Leads
    description: Partner CRM lead sync endpoints.
  - name: Attribution
    description: >-
      Partner marketing attribution, campaign analytics, and event ingestion
      endpoints.
  - name: Pipeline
    description: Partner-readable lead pipeline metadata.
  - name: Reports
    description: Partner report import, listing, fetch, export, and download endpoints.
  - name: Visualizer
    description: >-
      Partner Sales Visualizer creation, generation, hosted photo upload links,
      image reads, session history, and share-link endpoints.
  - name: Estimates
    description: Partner Budget Estimate creation and reads for the key-bound workspace.
  - name: Objects
    description: >-
      Partner Data Objects discovery, schema, records, relations, views, and
      admin endpoints.
paths:
  /api/v1/report-requests:
    post:
      tags:
        - Reports
      summary: Create report request
      description: >
        Creates a roof measurement report from a property address and starts the
        RoofKit AI measurement. The answer is 202 at once. A report takes about
        15 minutes. Poll the request, or subscribe a workspace webhook endpoint
        to `report_request.ready`, then read the measurements, the PDF and the
        3D model. A create with the `external_report_id` of a live request
        returns that request with 200 and starts no new report. When that
        request is ready and its 3D model failed or is missing, the create makes
        the model again, at most three times. The workspace pays the report as
        the app does.
      operationId: Create report request
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReportRequestCreateRequest'
            example:
              address: 100 Congress Ave, Austin, TX 78701
              lat: 30.2672
              lng: -97.7431
              external_report_id: inspection-77
              roof_material: shingle
      responses:
        '200':
          description: >-
            A live request with the same `external_report_id`. A ready request
            whose 3D model failed or is missing is back in `rendering`.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            Idempotency-Replayed:
              $ref: '#/components/headers/IdempotencyReplayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReportRequestResponse'
        '202':
          description: Report request created. The AI measurement runs in the background.
          headers:
            X-RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            X-RateLimit-Remaining:
              $ref: '#/components/headers/RateLimitRemaining'
            X-RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            Idempotency-Replayed:
              $ref: '#/components/headers/IdempotencyReplayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReportRequestResponse'
        '400':
          $ref: '#/components/responses/ValidationError'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/InsufficientCredits'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: >-
        A unique value for each new request, such as a UUID. Send the same value
        to retry a request safely. The same key and payload replay the first
        response with `Idempotency-Replayed: true`.
      schema:
        type: string
        minLength: 1
        maxLength: 160
  schemas:
    ReportRequestCreateRequest:
      type: object
      additionalProperties: false
      required:
        - address
      properties:
        address:
          type: string
          minLength: 3
          maxLength: 500
          example: 100 Congress Ave, Austin, TX 78701
        place_id:
          type:
            - string
            - 'null'
          maxLength: 500
          description: >-
            Google Places id. RoofKit uses it to locate the property when `lat`
            and `lng` are absent.
        lat:
          type: number
          minimum: -90
          maximum: 90
          description: >-
            Send with `lng`. Without both, RoofKit locates the address. The AI
            measures the building nearest to this point.
        lng:
          type: number
          minimum: -180
          maximum: 180
        external_report_id:
          type:
            - string
            - 'null'
          maxLength: 200
          description: >-
            Your id for this report, such as the inspection or job id. A live
            request with the same id is returned instead of a new report.
        roof_material:
          description: The roof finish. Without it, the team chooses it later in RoofKit.
          oneOf:
            - type: string
              enum:
                - shingle
                - tile
                - metal
            - type: 'null'
    ReportRequestResponse:
      type: object
      additionalProperties: false
      required:
        - report_request
      properties:
        report_request:
          $ref: '#/components/schemas/ReportRequest'
        reused:
          type: boolean
          description: >-
            True when a live request with the same `external_report_id` answered
            the create.
    ReportRequest:
      type: object
      additionalProperties: false
      required:
        - id
        - status
        - report_id
        - address
        - render_3d
        - created_at
        - updated_at
      properties:
        id:
          type: string
          example: rrq_00000000-0000-4000-8000-000000000000
        source:
          type: string
          description: >-
            Who asked for the report. `jobnimbus` is a request that an
            inspection booked in JobNimbus started.
          enum:
            - partner_api
            - jobnimbus
        status:
          type: string
          enum:
            - preparing
            - needs_attention
            - rendering
            - ready
            - failed
        attention_reason:
          oneOf:
            - type: string
              enum:
                - needs_outline
                - preparation_failed
                - insufficient_credits
            - type: 'null'
        failure_code:
          type:
            - string
            - 'null'
        report_id:
          type: string
        external_report_id:
          type:
            - string
            - 'null'
        address:
          type: string
        revision_id:
          type:
            - string
            - 'null'
        measurements:
          oneOf:
            - $ref: '#/components/schemas/ReportRequestMeasurements'
            - type: 'null'
        report_pdf:
          oneOf:
            - $ref: '#/components/schemas/ReportExportArtifact'
            - type: 'null'
        report_pdf_failure_code:
          type:
            - string
            - 'null'
        render_3d:
          type: object
          additionalProperties: false
          required:
            - status
          properties:
            status:
              type: string
              enum:
                - pending
                - ready
                - failed
            failure_code:
              type:
                - string
                - 'null'
            download_url:
              type:
                - string
                - 'null'
              format: uri
              description: >-
                The route that downloads the GLB of the house with the API key.
                Set when the status is ready.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        ready_at:
          type:
            - string
            - 'null'
          format: date-time
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
            - request_id
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            message:
              type: string
            request_id:
              type: string
            details:
              type: object
              additionalProperties: true
    ReportRequestMeasurements:
      type: object
      additionalProperties: true
      description: >
        The measurements of the revision the request delivered. Keys are stable
        snake_case with the unit in the name. `version` changes only when a key
        is renamed or removed. A new key does not change it. A request that was
        ready before 2026-10-28 keeps the measurements of that day, without the
        newer keys.
      required:
        - version
        - units
        - roof_area_sqft
        - roof_squares
        - facets
        - suggested_waste_pct
        - waste_table
        - area_by_pitch
        - lengths_ft
      properties:
        version:
          type: integer
          example: 1
        units:
          type: object
          properties:
            area:
              type: string
              example: sq_ft
            length:
              type: string
              example: ft
        roof_material:
          description: >
            The roof finish of the report, or null before the team picks one. It
            is the new roof, not the roof that is there now.
          oneOf:
            - type: string
              enum:
                - shingle
                - tile
                - metal
            - type: 'null'
        roof_area_sqft:
          type: number
          description: >-
            Measured roof area before waste, flat faces included. Slabs are not
            roof.
        roof_squares:
          type: number
        sloped_area_sqft:
          type: number
          description: >-
            Roof area of the faces that are not flat. Sloped plus flat is the
            roof area.
        sloped_squares:
          type: number
        flat_area_sqft:
          type: number
          description: >
            Roof area of the flat faces: a face marked as a flat roof, or a face
            under 2/12 after the rise rounds to a whole number.
        flat_squares:
          type: number
        steep_slope_area_sqft:
          type: number
          description: >
            Roof area at 8/12 or steeper after the rise rounds to a whole
            number. The `steep` band of `area_by_pitch_band_sqft` starts at
            10/12.
        steep_slope_squares:
          type: number
        predominant_pitch:
          type:
            - string
            - 'null'
          example: 6/12
        predominant_pitch_rise:
          type:
            - number
            - 'null'
        facets:
          type: integer
        suggested_waste_pct:
          type: number
        waste_table:
          type: array
          items:
            type: object
            properties:
              waste_pct:
                type: number
              area_sqft:
                type: number
              squares:
                type: number
              is_suggested:
                type: boolean
        area_by_pitch:
          type: array
          items:
            type: object
            properties:
              pitch:
                type:
                  - string
                  - 'null'
              pitch_rise:
                type:
                  - number
                  - 'null'
              area_sqft:
                type: number
              share_pct:
                type: number
        area_by_pitch_band_sqft:
          type: object
          properties:
            low:
              type: number
            mid:
              type: number
            steep:
              type: number
        unpitched_area_sqft:
          type: number
        lengths_ft:
          type: object
          description: >
            Line lengths in feet. These keys are the stable names of the roof
            lines. Every key is always present, 0 when the roof has no such
            line.
          required:
            - eaves
            - eaves_flat
            - eaves_sloped
            - rakes
            - ridges
            - hips
            - valleys
            - step_flashing
            - wall_flashing
            - parapets
            - slope_transitions
            - slope_transitions_pitch_to_pitch
            - slope_transitions_flat_to_pitch
            - drip_edge
            - starter
            - ridge_cap
            - ridge_vent
          properties:
            eaves:
              type: number
              description: Eave lines.
            eaves_flat:
              type: number
              description: Eave lines whose faces are all flat.
            eaves_sloped:
              type: number
              description: Eave lines of sloped faces, and eave lines with no face.
            rakes:
              type: number
              description: Rake lines.
            ridges:
              type: number
              description: Ridge lines.
            hips:
              type: number
              description: Hip lines.
            valleys:
              type: number
              description: Valley lines.
            step_flashing:
              type: number
              description: >-
                Step flashing and sidewall lines, where a wall runs up the
                slope.
            wall_flashing:
              type: number
              description: >-
                Apron flashing and endwall lines, where a level wall meets the
                roof.
            parapets:
              type: number
              description: Parapet lines, the low wall around a flat roof.
            slope_transitions:
              type: number
              description: Slope transition lines.
            slope_transitions_pitch_to_pitch:
              type: number
              description: Slope transition lines between two sloped faces.
            slope_transitions_flat_to_pitch:
              type: number
              description: Slope transition lines with a flat face on one side.
            drip_edge:
              type: number
              description: Eaves plus rakes.
            starter:
              type: number
              description: Eaves plus rakes.
            ridge_cap:
              type: number
              description: Ridges plus hips.
            ridge_vent:
              type: number
              description: Ridges, as the price book orders ridge vent.
        penetrations:
          type:
            - object
            - 'null'
          properties:
            skylights:
              type: integer
            chimneys:
              type: integer
            vents:
              type: integer
            pipe_boots:
              type: integer
        walls:
          type:
            - object
            - 'null'
          properties:
            perimeter_ft:
              type: number
            gable_area_sqft:
              type: number
        metal_panels:
          type:
            - object
            - 'null'
          properties:
            stock_ft:
              type: number
            piece_count:
              type: integer
            is_complete:
              type: boolean
    ReportExportArtifact:
      type: object
      additionalProperties: false
      required:
        - export_id
        - report_id
        - revision_id
        - format
        - file_name
        - mime_type
        - size_bytes
        - checksum
      properties:
        export_id:
          type: string
        report_id:
          type: string
        revision_id:
          type:
            - string
            - 'null'
        format:
          $ref: '#/components/schemas/ReportArtifactFormat'
        role:
          type: string
          enum:
            - export
            - manifest
        file_name:
          type: string
        mime_type:
          type: string
        size_bytes:
          type: integer
          minimum: 0
        checksum:
          type: string
        metadata:
          type: object
          additionalProperties: true
        created_at:
          type: string
          format: date-time
        download_url:
          type: string
          format: uri
    ErrorCode:
      type: string
      enum:
        - UNAUTHORIZED
        - FORBIDDEN
        - RATE_LIMITED
        - VALIDATION_ERROR
        - NOT_FOUND
        - CONFLICT
        - INSUFFICIENT_CREDITS
        - INTERNAL_ERROR
    ReportArtifactFormat:
      type: string
      enum:
        - xml
        - csv
        - xlsx
        - dxf
        - pdf
        - json
        - zip
        - manifest
        - tif
        - png
        - jpg
        - jpeg
        - webp
        - gif
  headers:
    RateLimitLimit:
      description: Maximum requests allowed in the current window.
      schema:
        type: string
    RateLimitRemaining:
      description: Requests remaining in the current window.
      schema:
        type: string
    RateLimitReset:
      description: ISO timestamp when the current rate-limit window resets.
      schema:
        type: string
        format: date-time
    IdempotencyReplayed:
      description: Present and true when a stored successful write response was replayed.
      schema:
        type: string
        enum:
          - 'true'
    RetryAfter:
      description: Seconds until the caller should retry.
      schema:
        type: string
  responses:
    ValidationError:
      description: Request payload, query, or required header is invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Missing, malformed, revoked, deleted, or unknown API key.
      headers:
        WWW-Authenticate:
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InsufficientCredits:
      description: The workspace cannot cover the credit charge for this operation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Forbidden:
      description: >-
        The API key lacks a required scope, or the workspace is not active. A
        scope failure names a missing scope in `details.required_scope`. When
        the key lookup refuses the call, `details.missing_scopes` lists every
        required scope that the key does not hold.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            missing_scope:
              summary: A Read-only key calls a write operation
              value:
                error:
                  code: FORBIDDEN
                  message: 'API key does not include the required scope: leads.write.'
                  request_id: req_123
                  details:
                    required_scope: leads.write
                    missing_scopes:
                      - leads.write
    Conflict:
      description: Request conflicts with idempotency or external event identity.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    RateLimited:
      description: Rate limit exceeded for this key and endpoint or invalid-auth bucket.
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/RateLimitLimit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/RateLimitRemaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/RateLimitReset'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    InternalError:
      description: Internal authentication or server error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  securitySchemes:
    ApiKeyBearer:
      type: http
      scheme: bearer
      bearerFormat: RoofKit API key
      description: 'Use `Authorization: Bearer rk_live_...`.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.