{
  "openapi": "3.1.0",
  "info": {
    "title": "Creditable Founder Submission API",
    "version": "2026-10-26",
    "description": "Private startup intake. Founder permission required. No account/API key needed. No public read endpoint. A submission creates no partnership commitment.",
    "contact": {
      "name": "Creditable",
      "email": "jack@creditable.vc",
      "url": "https://creditable.vc"
    }
  },
  "servers": [
    {
      "url": "https://creditable.vc"
    }
  ],
  "paths": {
    "/api/v1/submissions": {
      "post": {
        "operationId": "submitFounderProject",
        "summary": "Submit an idea, project or deck for review",
        "security": [],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "A new UUID per submission. Reuse the same key and body for retries.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Submission"
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "application": {
                    "type": "string",
                    "description": "JSON string matching Submission. Maximum 64,000 characters."
                  },
                  "attachment": {
                    "type": "string",
                    "format": "binary",
                    "description": "Optional real PDF, PNG or JPG; maximum 3 MiB."
                  }
                },
                "required": [
                  "application"
                ]
              },
              "encoding": {
                "application": {
                  "contentType": "application/json"
                },
                "attachment": {
                  "contentType": "application/pdf, image/png, image/jpeg"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Identical retry: original saved reference.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "reference": {
                      "type": "string",
                      "pattern": "^CR-[A-F0-9]{12}$"
                    },
                    "saved": {
                      "const": true
                    },
                    "status": {
                      "const": "received"
                    },
                    "intake_type": {
                      "const": "startup_submission"
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "reference",
                    "saved",
                    "status",
                    "intake_type"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Saved privately for review; not selection or funding.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "reference": {
                      "type": "string",
                      "pattern": "^CR-[A-F0-9]{12}$"
                    },
                    "saved": {
                      "const": true
                    },
                    "status": {
                      "const": "received"
                    },
                    "intake_type": {
                      "const": "startup_submission"
                    },
                    "replayed": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "reference",
                    "saved",
                    "status",
                    "intake_type"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Missing/invalid UUID Idempotency-Key or malformed JSON/multipart.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "fields": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Browser Origin is not allowed. Server-side clients can omit Origin.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "fields": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "409": {
            "description": "Same key used with a different normalized payload or file.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "fields": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "413": {
            "description": "JSON >64 KiB, multipart >4 MiB, or attachment >3 MiB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "fields": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "415": {
            "description": "Unsupported Content-Type.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "fields": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "422": {
            "description": "Invalid fields, file signature, missing consent or agent authorization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "fields": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Five new attempts per IP/hour; respect Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "fields": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds before identical retry."
              }
            }
          },
          "503": {
            "description": "Storage/configuration unavailable or write not confirmed; respect Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "fields": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds before identical retry."
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Submission": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "applicant": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              "email": {
                "type": "string",
                "maxLength": 254,
                "format": "email"
              }
            },
            "required": [
              "name",
              "email"
            ]
          },
          "project": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              "summary": {
                "type": "string",
                "maxLength": 8000,
                "minLength": 10
              },
              "website": {
                "type": "string",
                "format": "uri",
                "maxLength": 2000,
                "pattern": "^https?://"
              }
            },
            "required": [
              "name",
              "summary"
            ]
          },
          "materials": {
            "type": "array",
            "maxItems": 10,
            "default": [],
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "type": {
                  "enum": [
                    "deck",
                    "demo",
                    "video",
                    "other"
                  ]
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "maxLength": 2000,
                  "pattern": "^https?://"
                }
              },
              "required": [
                "type",
                "url"
              ]
            }
          },
          "context": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "stage": {
                "type": "string",
                "maxLength": 100,
                "default": ""
              },
              "sector": {
                "type": "string",
                "maxLength": 200,
                "default": ""
              },
              "country": {
                "type": "string",
                "maxLength": 100,
                "default": ""
              }
            },
            "required": [],
            "default": {}
          },
          "submitted_by": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "type": {
                "enum": [
                  "founder",
                  "agent"
                ]
              },
              "name": {
                "type": "string",
                "maxLength": 200,
                "default": ""
              },
              "founder_authorized": {
                "type": "boolean"
              }
            },
            "required": [
              "type"
            ],
            "allOf": [
              {
                "if": {
                  "properties": {
                    "type": {
                      "const": "agent"
                    }
                  },
                  "required": [
                    "type"
                  ]
                },
                "then": {
                  "properties": {
                    "founder_authorized": {
                      "const": true
                    }
                  },
                  "required": [
                    "founder_authorized"
                  ]
                }
              }
            ]
          },
          "consent": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "review_and_contact": {
                "type": "boolean",
                "enum": [
                  true
                ]
              }
            },
            "required": [
              "review_and_contact"
            ]
          },
          "source": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "platform": {
                "type": "string",
                "maxLength": 200,
                "default": ""
              },
              "medium": {
                "type": "string",
                "maxLength": 100,
                "default": ""
              },
              "campaign": {
                "type": "string",
                "maxLength": 200,
                "default": ""
              },
              "referrer": {
                "type": "string",
                "maxLength": 300,
                "default": ""
              }
            },
            "required": [],
            "default": {}
          },
          "contactWebsite": {
            "type": "string",
            "maxLength": 1000,
            "default": "",
            "description": "Honeypot: omit or leave empty."
          }
        },
        "required": [
          "applicant",
          "project",
          "submitted_by",
          "consent"
        ],
        "description": "All strings are trimmed. Agent submissions must set submitted_by.founder_authorized=true after the founder approves review and follow-up. No eligibility restrictions on stage, sector or country."
      },
      "Receipt": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "reference": {
            "type": "string",
            "pattern": "^CR-[A-F0-9]{12}$"
          },
          "saved": {
            "const": true
          },
          "status": {
            "const": "received"
          },
          "intake_type": {
            "const": "startup_submission"
          },
          "replayed": {
            "type": "boolean"
          }
        },
        "required": [
          "reference",
          "saved",
          "status",
          "intake_type"
        ]
      }
    }
  }
}
