openapi: 3.0.3
info:
  title: GrowLeafy Identity — Enterprise API
  version: 1.0.0
  description: >
    One identity platform for the physical world. All endpoints below are the
    REAL implemented routes. Authentication: Bearer token from
    POST /api/v1/partner-api/token (client credentials) or user Sanctum tokens.
    Errors use {error:{code,message,request_id}}; every response carries X-Request-ID.
servers:
  - url: https://growleafy.in/api/v1
tags:
  - name: Token
  - name: Organizations
  - name: Fleets & Drivers
  - name: Assets & Maintenance
  - name: Webhooks
security:
  - bearerAuth: []
paths:
  /partner-api/token:
    post:
      tags: [Token]
      summary: Exchange client credentials for a scoped access token
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [client_id, client_secret]
              properties:
                client_id: { type: string, example: pk_abc123 }
                client_secret: { type: string, example: "secret-shown-once" }
            example: { client_id: pk_abc123, client_secret: "secret-shown-once" }
      responses:
        '200':
          description: Bearer token with the client's scopes as abilities
          content:
            application/json:
              example: { token: "2|...", token_type: Bearer }
        '401':
          description: invalid_credentials
  /organizations:
    get:
      tags: [Organizations]
      summary: List organizations the user belongs to
      responses:
        '200': { description: organizations array }
    post:
      tags: [Organizations]
      summary: Create an organization
      responses:
        '201': { description: created }
  /organizations/{organization}/fleets:
    get:
      tags: [Fleets & Drivers]
      summary: List fleets (scope fleet:read)
      parameters:
        - { name: organization, in: path, required: true, schema: { type: string } }
      responses:
        '200': { description: fleets array }
        '403': { description: SCOPE_REQUIRED }
    post:
      tags: [Fleets & Drivers]
      summary: Create a fleet (scope fleet:write)
      responses:
        '201': { description: created }
  /organizations/{organization}/drivers:
    get:
      tags: [Fleets & Drivers]
      summary: List drivers (scope drivers:read)
      responses: { '200': { description: drivers array } }
    post:
      tags: [Fleets & Drivers]
      summary: Create a driver (scope drivers:write)
      responses: { '201': { description: created } }
  /organizations/{organization}/vehicles:
    get:
      tags: [Assets & Maintenance]
      summary: List dealer/OEM vehicles (scope assets:read)
      parameters:
        - { name: updated_since, in: query, required: false, schema: { type: string, format: date-time } }
        - { name: external_reference, in: query, required: false, schema: { type: string } }
      responses: { '200': { description: vehicles array } }
    post:
      tags: [Assets & Maintenance]
      summary: Register a dealer vehicle with external_reference (scope assets:write)
      responses: { '201': { description: created } }
  /organizations/{organization}/oem-vehicles:
    post:
      tags: [Assets & Maintenance]
      summary: Register an OEM vehicle (scope assets:write)
      responses: { '201': { description: created } }
  /organizations/{organization}/maintenance:
    get:
      tags: [Assets & Maintenance]
      summary: Maintenance history (scope maintenance:read)
      responses: { '200': { description: records } }
    post:
      tags: [Assets & Maintenance]
      summary: Create a maintenance record (scope maintenance:write)
      responses: { '201': { description: created } }
  /organizations/{organization}/custody:
    get:
      tags: [Assets & Maintenance]
      summary: Custody history — append-only (scope custody:read)
      responses: { '200': { description: history } }
    post:
      tags: [Assets & Maintenance]
      summary: Assign custody (scope custody:write)
      responses: { '201': { description: assigned } }
  /organizations/{organization}/webhook-endpoints:
    get:
      tags: [Webhooks]
      summary: List webhook endpoints (scope webhooks:read)
      responses: { '200': { description: endpoints } }
    post:
      tags: [Webhooks]
      summary: Create a webhook endpoint (scope webhooks:write)
      responses: { '201': { description: created } }
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
  schemas:
    Error:
      type: object
      required: [error]
      properties:
        error:
          type: object
          required: [code, message, request_id]
          properties:
            code: { type: string, example: SCOPE_REQUIRED }
            message: { type: string }
            request_id: { type: string, example: req_abc123 }
securityDefinitions:
  webhookSignature:
    type: apiKey
    in: header
    name: X-GrowLeafy-Signature
    description: 'sha256=HMAC_SHA256(timestamp + "." + raw_body, webhook_secret)'
