{"public_endpoints":{"api_root":"https://api.atgc-montpellier.fr/rest/","list_services":"https://api.atgc-montpellier.fr/rest/services/","openapi_schema":"https://api.atgc-montpellier.fr/rest/openapi/","data_libraries":"https://api.atgc-montpellier.fr/rest/data-libraries/","recipes":"https://api.atgc-montpellier.fr/rest/recipes/","chunk_upload":"https://api.atgc-montpellier.fr/rest/uploads/chunk/","email_verification":"https://api.atgc-montpellier.fr/rest/email-verification/verify/"},"job_endpoints":{"submit_job_template":"https://api.atgc-montpellier.fr/rest/services/{service_slug}/jobs/","submit_job_form_template":"https://api.atgc-montpellier.fr/rest/services/{service_slug}/jobs/form/","job_status_template":"https://api.atgc-montpellier.fr/rest/jobs/{job_id}/status/","job_status_stream_template":"https://api.atgc-montpellier.fr/rest/jobs/{job_id}/status/stream/","expire_job_template":"https://api.atgc-montpellier.fr/rest/jobs/{job_id}/expire/"},"documentation":{"title":"ATGC REST API quickstart","summary":"Use /rest/services/ to discover enabled services, then submit jobs and follow their status via SSE or JSON.","workflow":["0. Download the machine-readable OpenAPI schema at /rest/openapi/.","1. Discover services and submission URLs with GET /rest/services/.","2. (Optional) Discover server-side reference files with GET /rest/data-libraries/.","3. (Optional) Browse downloadable container recipes with GET /rest/recipes/.","4. Submit a job with POST /rest/services/{service_slug}/jobs/.","5. Prefer live status streaming with GET /rest/jobs/{job_id}/status/stream/ (text/event-stream).","6. Use GET /rest/jobs/{job_id}/status/ for one-shot JSON checks or fallbacks.","7. If email verification is required, verify the token at /rest/email-verification/verify/."],"notes":["File fields accept either multipart uploads or upload:// tokens from chunk upload.","Some services expose an HTML form at /rest/services/{service_slug}/jobs/form/."]},"examples":{"list_services":{"description":"List enabled services and their submit_job_url values.","method":"GET","url":"https://api.atgc-montpellier.fr/rest/services/","curl":"curl -X GET \"https://api.atgc-montpellier.fr/rest/services/\""},"list_recipes":{"description":"List downloadable Singularity/Apptainer recipes exposed by enabled services.","method":"GET","url":"https://api.atgc-montpellier.fr/rest/recipes/","curl":"curl -X GET \"https://api.atgc-montpellier.fr/rest/recipes/\""},"submit_job_multipart":{"description":"Submit a job with multipart form-data (adapt fields to the selected service).","method":"POST","url_template":"https://api.atgc-montpellier.fr/rest/services/{service_slug}/jobs/","curl_template":"curl -X POST \"{base_url}/rest/services/{service_slug}/jobs/\" -H \"X-ATGC-Submission-Source: cli-restapi\" -F \"name=demo-job\" -F \"email=user@example.com\" -F \"confirm_email=user@example.com\" -F \"<input_clean_name>=<value_or_@/path/to/file>\""},"check_job_status":{"description":"Retrieve status, timestamps and results URL for a job.","method":"GET","url_template":"https://api.atgc-montpellier.fr/rest/jobs/{job_id}/status/","curl_template":"curl -X GET \"{base_url}/rest/jobs/{job_id}/status/\""},"stream_job_status":{"description":"Subscribe to live job status updates over Server-Sent Events.","method":"GET","url_template":"https://api.atgc-montpellier.fr/rest/jobs/{job_id}/status/stream/","curl_template":"curl -N -H \"Accept: text/event-stream\" \"{base_url}/rest/jobs/{job_id}/status/stream/\""},"verify_email":{"description":"Verify the signed token received by email and release waiting jobs.","method":"GET","url_template":"https://api.atgc-montpellier.fr/rest/email-verification/verify/?token={signed_token}","curl_template":"curl -X GET \"{base_url}/rest/email-verification/verify/?token={signed_token}\""},"chunk_upload":{"description":"Upload large files by chunks, then use upload:// tokens in job submissions.","method":"PUT","url":"https://api.atgc-montpellier.fr/rest/uploads/chunk/","curl_template":"curl -X PUT \"{base_url}/rest/uploads/chunk/\" -H \"Upload-Id: <uuid>\" -H \"X-File-Name: big_input.fasta\" -H \"X-File-Size: <total_bytes>\" -H \"Content-Range: bytes <start>-<end>/<total_bytes>\" --data-binary @chunk.bin"}}}