{
  "schema_version": "1.0",
  "name": "FieldRobin signup flow",
  "description": "Public account creation and post-registration onboarding contract.",
  "updated_at": "2026-09-22",
  "company": "Doorkeeper Labs LLC",
  "signup_url": "https://fieldrobin.com/signup",
  "register_url": "https://fieldrobin.com/register",
  "documentation_url": "https://fieldrobin.com/signup.md",
  "manifest_url": "https://fieldrobin.com/.well-known/signup.json",
  "registration_status": {
    "method": "GET",
    "url": "https://fieldrobin.com/api/v1/auth/registration",
    "authentication": "none",
    "description": "Returns the live open-registration or invite-only mode."
  },
  "registration": {
    "method": "POST",
    "url": "https://fieldrobin.com/api/v1/register",
    "authentication": "none",
    "content_type": "application/json",
    "required_fields": [
      "email",
      "password",
      "password_confirmation"
    ],
    "fields": {
      "email": {
        "type": "string",
        "format": "email",
        "max_length": 255
      },
      "password": {
        "type": "string",
        "min_length": 8,
        "sensitive": true
      },
      "password_confirmation": {
        "type": "string",
        "matches": "password",
        "sensitive": true
      },
      "name": {
        "type": "string",
        "nullable": true,
        "max_length": 255
      },
      "business_name": {
        "type": "string",
        "nullable": true,
        "max_length": 255
      },
      "trade_type": {
        "type": "string",
        "nullable": true,
        "max_length": 100
      },
      "plan": {
        "type": "string",
        "enum": [
          "free",
          "pro",
          "team"
        ],
        "default": "free"
      },
      "invite_token": {
        "type": "string",
        "length": 64,
        "required_when": "invite_only",
        "sensitive": true
      },
      "include_token": {
        "type": "boolean",
        "default": false,
        "native_only": true
      },
      "turnstile_token": {
        "type": "string",
        "conditional": "browser_bot_protection",
        "sensitive": true
      },
      "cf-turnstile-response": {
        "type": "string",
        "conditional": "browser_bot_protection",
        "sensitive": true
      }
    },
    "browser_authentication": "HttpOnly cookie",
    "native_authentication": "Bearer token when X-FieldRobin-Client is ios or android and include_token is true",
    "bot_protection": "Browser Turnstile is required when configured by the server.",
    "honeypot_field": {
      "name": "website",
      "behavior": "prohibited; never send"
    }
  },
  "branches": [
    {
      "when": "registration_open=true",
      "next": "POST registration directly after explicit user approval"
    },
    {
      "when": "registration_open=false",
      "next": "Supply a matching approved invite_token or direct the person to request access"
    }
  ],
  "success": {
    "status": 201,
    "response_fields": [
      "user",
      "selected_plan",
      "trial_started",
      "email_verification_required",
      "token_native_only"
    ],
    "onboarding_url": "https://fieldrobin.com/app/onboarding",
    "verification_url": "https://fieldrobin.com/app/verify-email",
    "note": "Unverified users can save onboarding; protected workspace data remains gated until verification when required."
  },
  "onboarding": {
    "get": {
      "method": "GET",
      "url": "https://fieldrobin.com/api/v1/onboarding",
      "authentication": "session or bearer token",
      "response_sections": [
        "state",
        "flow.step_ids",
        "flow.current_step_id",
        "prefill",
        "capabilities",
        "activation",
        "preview"
      ]
    },
    "upsert": {
      "method": "POST",
      "url": "https://fieldrobin.com/api/v1/onboarding",
      "authentication": "session or bearer token",
      "actions": [
        "draft",
        "complete"
      ]
    }
  },
  "retry": {
    "header": "Idempotency-Key",
    "optional": true,
    "maximum_length": 128,
    "same_request": "Replays the original response with Idempotency-Replayed: true.",
    "different_request": "409 IDEMPOTENCY_KEY_REUSED",
    "concurrent_request": "409 IDEMPOTENCY_REQUEST_IN_PROGRESS with Retry-After",
    "retention": "Short-lived server receipt; default 60 minutes and operator-configurable.",
    "default_retention_minutes": 60,
    "in_progress_lock_seconds": 120,
    "never_include": [
      "password",
      "password_confirmation",
      "invite_token",
      "turnstile_token",
      "raw credentials"
    ]
  },
  "errors": {
    "403": [
      "REGISTRATION_CLOSED",
      "INVITE_INVALID"
    ],
    "409": [
      "IDEMPOTENCY_KEY_REUSED",
      "IDEMPOTENCY_REQUEST_IN_PROGRESS",
      "REGISTRATION_REPLAY_UNAVAILABLE"
    ],
    "422": [
      "validation_error",
      "TURNSTILE_FAILED",
      "INVALID_IDEMPOTENCY_KEY"
    ],
    "429": [
      "rate_limit; honor Retry-After"
    ]
  },
  "safety": {
    "account_creation_requires_explicit_user_approval": true,
    "do_not_log": [
      "passwords",
      "invite tokens",
      "Turnstile tokens",
      "auth cookies",
      "bearer tokens",
      "raw idempotency keys"
    ],
    "do_not_submit": [
      "website honeypot field"
    ]
  }
}