{
  "openapi": "3.0.1",
  "info": {
    "title": "IVOA TAP Catalog Extractor",
    "description": "Point at ANY IVOA TAP service (VizieR, Gaia, GAVO, MAST, ESO, CADC and thousands of observatory archives) and run an ADQL query over the Table Access Protocol. Query mode returns dynamic columns per your SELECT; tables mode discovers the full schema. One actor, every astronomical catalog.",
    "version": "0.1",
    "x-build-id": "xgsXrwJIb8hhx6c8Y"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/datamule~ivoa-tap-extractor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-datamule-ivoa-tap-extractor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/datamule~ivoa-tap-extractor/runs": {
      "post": {
        "operationId": "runs-sync-datamule-ivoa-tap-extractor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/datamule~ivoa-tap-extractor/run-sync": {
      "post": {
        "operationId": "run-sync-datamule-ivoa-tap-extractor",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "endpoint": {
            "title": "TAP service base URL",
            "type": "string",
            "description": "The base URL of ANY IVOA TAP service (Table Access Protocol 1.0 / 1.1). ONE actor speaks to all of them — VizieR / CDS (http://tapvizier.cds.unistra.fr/TAPVizieR/tap), Gaia / ESA (https://gea.esac.esa.int/tap-server/tap), GAVO (https://dc.g-vo.org/tap), MAST, ESO, NOIRLab, CADC and thousands of observatory data centres. Give the base ending in .../tap — the actor appends /sync for queries and /tables for discovery (a full .../tap/sync or .../tap/tables URL is also accepted). Required unless you use \"Endpoints\" below. For an auth-gated deployment, add a Bearer token or headers below."
          },
          "endpoints": {
            "title": "Endpoints (run the same query across several)",
            "type": "array",
            "description": "Optional: run the SAME ADQL query across multiple TAP services at once (mirrors, or several astronomical archives). Each output row is tagged with its _endpoint. Use this OR the single \"Endpoint\" above (at least one is required). An endpoint that is unreachable, auth-gated, or returns a non-VOTable body is skipped with a warning and the batch continues.",
            "items": {
              "type": "string"
            }
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "query",
              "tables"
            ],
            "type": "string",
            "description": "query = run an ADQL query and return one row per result row (columns are your query's SELECT columns). tables = fetch the service's VOSI /tables metadata and return one row per column — a cross-service data dictionary (schema / table / column / datatype / unit / UCD / description).",
            "default": "query"
          },
          "adql": {
            "title": "ADQL query",
            "type": "string",
            "description": "The ADQL query to run (used in query mode). The output COLUMNS are exactly your SELECT columns, so shape the result by shaping the query. A portable query that works on almost every TAP service (tap_schema is mandatory in TAP): SELECT TOP 100 * FROM tap_schema.tables. Discover a table's columns with: SELECT * FROM tap_schema.columns WHERE table_name = 'your.table'. Use TOP N (ADQL) to limit rows server-side."
          },
          "method": {
            "title": "HTTP method",
            "enum": [
              "GET",
              "POST"
            ],
            "type": "string",
            "description": "How to send the query to /sync. GET (default) puts the query in the URL — fine for most queries. POST sends it as a form body — use it for long ADQL queries that would overflow a URL.",
            "default": "GET"
          },
          "maxRecords": {
            "title": "Max records (global cap)",
            "minimum": 1,
            "type": "integer",
            "description": "A GLOBAL cap on the number of rows emitted across ALL endpoints (each row is one billable event). Reached mid-endpoint, the run stops deterministically. In query mode it is also sent to the server as MAXREC so the server itself limits the result. Leave empty to emit everything the query / tableset returns."
          },
          "lang": {
            "title": "Query language",
            "type": "string",
            "description": "The TAP query language. ADQL is the universal default and what almost every service speaks. Only change this for the rare service that documents another language (e.g. PQL).",
            "default": "ADQL"
          },
          "userAgent": {
            "title": "User-Agent override",
            "type": "string",
            "description": "Optional override for the request User-Agent. A descriptive User-Agent is sent by default — some data centres throttle or reject a blank / generic UA. Only override if a specific service asks you to identify differently."
          },
          "timeoutSecs": {
            "title": "Read timeout (seconds)",
            "minimum": 1,
            "maximum": 900,
            "type": "integer",
            "description": "How long to wait for the service to answer (default 120). Astronomical queries over large catalogues can be slow; services also enforce their own server-side query timeouts, so a very large query may still be cut off by the server."
          },
          "bearer": {
            "title": "Bearer token",
            "type": "string",
            "description": "Optional bearer token for an auth-gated TAP deployment (sent as Authorization: Bearer ...). NOT required for public services. Never logged."
          },
          "extraHeaders": {
            "title": "Extra request headers",
            "type": "object",
            "description": "Optional extra HTTP headers as a JSON object, e.g. {\"X-Api-Key\": \"...\"} for a gateway-fronted service. Not required for public services. Header values are never logged."
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}