openapi: 3.0.0 info: description: '# Introducción Documentación del API de Contalink # Autenticación El método de autenticación para el api de contalink es mediante un api key el cual está relacionado forzosamente a un usuario dentro del sistema, por lo cual, todas las peticiones utilizando ese api key quedarán registradas como peticiones del usuario relacionado. ' title: API Contalink Balanza de comprobación Cargar un documento fiscal API version: 1.0.4 x-logo: altText: Contalink url: http://apidocs.contalink.com/logocontalinknew.svg servers: - description: prod url: https://794lol2h95.execute-api.us-east-1.amazonaws.com/prod tags: - description: Carga un documento fiscal al sistema name: Cargar un documento fiscal paths: /invoices/upload/: post: description: Endpoint para subir documentos fiscales a Contalink. Es importante señalar que la subida de documentos al sistema es asíncrona. La respuesta de este endpoint contiene una URL de Google Firebase donde se puede consultar el status de la carga. requestBody: content: application/json: schema: $ref: '#/components/schemas/UploadXML' required: true responses: '200': content: application/json: schema: $ref: '#/components/schemas/UploadXMLResult' description: 0 indica error, 1 indica éxito security: - APIKey: [] summary: Sube un documento a Contalink tags: - Cargar un documento fiscal x-codeSamples: - lang: C source: "CURL *curl;\nCURLcode res;\ncurl = curl_easy_init();\nif(curl) {\n curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, \"POST\");\n curl_easy_setopt(curl, CURLOPT_URL, \"%7B%7BbaseUrl%7D%7D/invoices/upload/\");\n curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);\n curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, \"https\");\n struct curl_slist *headers = NULL;\n headers = curl_slist_append(headers, \"Content-Type: application/json\");\n headers = curl_slist_append(headers, \"Accept: application/json\");\n headers = curl_slist_append(headers, \"Content-Length: \");\n curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);\n const char *data = \"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\";\n curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);\n res = curl_easy_perform(curl);\n}\ncurl_easy_cleanup(curl);\n" - lang: C# source: 'var client = new RestClient("{{baseUrl}}/invoices/upload/"); client.Timeout = -1; var request = new RestRequest(Method.POST); request.AddHeader("Content-Type", "application/json"); request.AddHeader("Accept", "application/json"); var body = @"{" + "\n" + @" ""xml"": """"," + "\n" + @" ""name"": """"" + "\n" + @"}"; request.AddParameter("application/json", body, ParameterType.RequestBody); IRestResponse response = client.Execute(request); Console.WriteLine(response.Content);' - lang: Curl source: "curl --location -g --request POST '{{baseUrl}}/invoices/upload/' \\\n--header 'Content-Type: application/json' \\\n--header 'Accept: application/json' \\\n--data-raw '{\n \"xml\": \"\",\n \"name\": \"\"\n}'" - lang: Dart source: "var headers = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json'\n};\nvar request = http.Request('POST', Uri.parse('{{baseUrl}}/invoices/upload/'));\nrequest.body = json.encode({\n \"xml\": \"\",\n \"name\": \"\"\n});\nrequest.headers.addAll(headers);\n\nhttp.StreamedResponse response = await request.send();\n\nif (response.statusCode == 200) {\n print(await response.stream.bytesToString());\n}\nelse {\n print(response.reasonPhrase);\n}\n" - lang: Go source: "package main\n\nimport (\n \"fmt\"\n \"strings\"\n \"net/http\"\n \"io/ioutil\"\n)\n\nfunc main() {\n\n url := \"%7B%7BbaseUrl%7D%7D/invoices/upload/\"\n method := \"POST\"\n\n payload := strings.NewReader(`{\n \"xml\": \"\",\n \"name\": \"\"\n}`)\n\n client := &http.Client {\n }\n req, err := http.NewRequest(method, url, payload)\n\n if err != nil {\n fmt.Println(err)\n return\n }\n req.Header.Add(\"Content-Type\", \"application/json\")\n req.Header.Add(\"Accept\", \"application/json\")\n\n res, err := client.Do(req)\n if err != nil {\n fmt.Println(err)\n return\n }\n defer res.Body.Close()\n\n body, err := ioutil.ReadAll(res.Body)\n if err != nil {\n fmt.Println(err)\n return\n }\n fmt.Println(string(body))\n}" - lang: Http source: "POST /invoices/upload/ HTTP/1.1\nHost: {{baseUrl}}\nContent-Type: application/json\nAccept: application/json\nContent-Length: 45\n\n{\n \"xml\": \"\",\n \"name\": \"\"\n}" - lang: Java source: "OkHttpClient client = new OkHttpClient().newBuilder()\n .build();\nMediaType mediaType = MediaType.parse(\"application/json\");\nRequestBody body = RequestBody.create(mediaType, \"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\");\nRequest request = new Request.Builder()\n .url(\"{{baseUrl}}/invoices/upload/\")\n .method(\"POST\", body)\n .addHeader(\"Content-Type\", \"application/json\")\n .addHeader(\"Accept\", \"application/json\")\n .addHeader(\"Content-Length\", \"\")\n .build();\nResponse response = client.newCall(request).execute();" - lang: Java source: "Unirest.setTimeouts(0, 0);\nHttpResponse response = Unirest.post(\"{{baseUrl}}/invoices/upload/\")\n .header(\"Content-Type\", \"application/json\")\n .header(\"Accept\", \"application/json\")\n .header(\"Content-Length\", \"\")\n .body(\"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\")\n .asString();\n" - lang: JavaScript source: "var myHeaders = new Headers();\nmyHeaders.append(\"Content-Type\", \"application/json\");\nmyHeaders.append(\"Accept\", \"application/json\");\nmyHeaders.append(\"Content-Length\", \"\");\n\nvar raw = JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n});\n\nvar requestOptions = {\n method: 'POST',\n headers: myHeaders,\n body: raw,\n redirect: 'follow'\n};\n\nfetch(\"{{baseUrl}}/invoices/upload/\", requestOptions)\n .then(response => response.text())\n .then(result => console.log(result))\n .catch(error => console.log('error', error));" - lang: JavaScript source: "var data = JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n});\n\nvar xhr = new XMLHttpRequest();\nxhr.withCredentials = true;\n\nxhr.addEventListener(\"readystatechange\", function() {\n if(this.readyState === 4) {\n console.log(this.responseText);\n }\n});\n\nxhr.open(\"POST\", \"%7B%7BbaseUrl%7D%7D/invoices/upload/\");\nxhr.setRequestHeader(\"Content-Type\", \"application/json\");\nxhr.setRequestHeader(\"Accept\", \"application/json\");\nxhr.setRequestHeader(\"Content-Length\", \"\");\n\nxhr.send(data);" - lang: JavaScript source: "var settings = {\n \"url\": \"{{baseUrl}}/invoices/upload/\",\n \"method\": \"POST\",\n \"timeout\": 0,\n \"headers\": {\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\",\n \"Content-Length\": \"\"\n },\n \"data\": JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n }),\n};\n\n$.ajax(settings).done(function (response) {\n console.log(response);\n});" - lang: NodeJS source: "var axios = require('axios');\nvar data = JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n});\n\nvar config = {\n method: 'post',\n url: '{{baseUrl}}/invoices/upload/',\n headers: { \n 'Content-Type': 'application/json', \n 'Accept': 'application/json', \n 'Content-Length': ''\n },\n data : data\n};\n\naxios(config)\n.then(function (response) {\n console.log(JSON.stringify(response.data));\n})\n.catch(function (error) {\n console.log(error);\n});\n" - lang: NodeJS source: "var https = require('follow-redirects').https;\nvar fs = require('fs');\n\nvar options = {\n 'method': 'POST',\n 'hostname': '{{baseUrl}}',\n 'path': '/invoices/upload/',\n 'headers': {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Content-Length': ''\n },\n 'maxRedirects': 20\n};\n\nvar req = https.request(options, function (res) {\n var chunks = [];\n\n res.on(\"data\", function (chunk) {\n chunks.push(chunk);\n });\n\n res.on(\"end\", function (chunk) {\n var body = Buffer.concat(chunks);\n console.log(body.toString());\n });\n\n res.on(\"error\", function (error) {\n console.error(error);\n });\n});\n\nvar postData = JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n});\n\nreq.write(postData);\n\nreq.end();" - lang: NodeJS source: "var request = require('request');\nvar options = {\n 'method': 'POST',\n 'url': '{{baseUrl}}/invoices/upload/',\n 'headers': {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Content-Length': ''\n },\n body: JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n })\n\n};\nrequest(options, function (error, response) {\n if (error) throw new Error(error);\n console.log(response.body);\n});\n" - lang: NodeJS source: "var unirest = require('unirest');\nvar req = unirest('POST', '{{baseUrl}}/invoices/upload/')\n .headers({\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Content-Length': ''\n })\n .send(JSON.stringify({\n \"xml\": \"\",\n \"name\": \"\"\n }))\n .end(function (res) { \n if (res.error) throw new Error(res.error); \n console.log(res.raw_body);\n });\n" - lang: Objective-C source: "#import \n\ndispatch_semaphore_t sema = dispatch_semaphore_create(0);\n\nNSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@\"%7B%7BbaseUrl%7D%7D/invoices/upload/\"]\n cachePolicy:NSURLRequestUseProtocolCachePolicy\n timeoutInterval:10.0];\nNSDictionary *headers = @{\n @\"Content-Type\": @\"application/json\",\n @\"Accept\": @\"application/json\",\n @\"Content-Length\": @\"\"\n};\n\n[request setAllHTTPHeaderFields:headers];\nNSData *postData = [[NSData alloc] initWithData:[@\"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\" dataUsingEncoding:NSUTF8StringEncoding]];\n[request setHTTPBody:postData];\n\n[request setHTTPMethod:@\"POST\"];\n\nNSURLSession *session = [NSURLSession sharedSession];\nNSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request\ncompletionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {\n if (error) {\n NSLog(@\"%@\", error);\n dispatch_semaphore_signal(sema);\n } else {\n NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;\n NSError *parseError = nil;\n NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];\n NSLog(@\"%@\",responseDictionary);\n dispatch_semaphore_signal(sema);\n }\n}];\n[dataTask resume];\ndispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);" - lang: OcaML source: "open Lwt\nopen Cohttp\nopen Cohttp_lwt_unix\n\nlet postData = ref \"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\";;\n\nlet reqBody = \n let uri = Uri.of_string \"%7B%7BbaseUrl%7D%7D/invoices/upload/\" in\n let headers = Header.init ()\n |> fun h -> Header.add h \"Content-Type\" \"application/json\"\n |> fun h -> Header.add h \"Accept\" \"application/json\"\n |> fun h -> Header.add h \"Content-Length\" \"\"\n in\n let body = Cohttp_lwt.Body.of_string !postData in\n\n Client.call ~headers ~body `POST uri >>= fun (_resp, body) ->\n body |> Cohttp_lwt.Body.to_string >|= fun body -> body\n\nlet () =\n let respBody = Lwt_main.run reqBody in\n print_endline (respBody)" - lang: PHP source: "setUrl('{{baseUrl}}/invoices/upload/');\n$request->setMethod(HTTP_Request2::METHOD_POST);\n$request->setConfig(array(\n 'follow_redirects' => TRUE\n));\n$request->setHeader(array(\n 'Content-Type' => 'application/json',\n 'Accept' => 'application/json',\n 'Content-Length' => ''\n));\n$request->setBody('{\\n \"xml\": \"\",\\n \"name\": \"\"\\n}');\ntry {\n $response = $request->send();\n if ($response->getStatus() == 200) {\n echo $response->getBody();\n }\n else {\n echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .\n $response->getReasonPhrase();\n }\n}\ncatch(HTTP_Request2_Exception $e) {\n echo 'Error: ' . $e->getMessage();\n}" - lang: PHP source: " '%7B%7BbaseUrl%7D%7D/invoices/upload/',\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => '',\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 0,\n CURLOPT_FOLLOWLOCATION => true,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => 'POST',\n CURLOPT_POSTFIELDS =>'{\n \"xml\": \"\",\n \"name\": \"\"\n}',\n CURLOPT_HTTPHEADER => array(\n 'Content-Type: application/json',\n 'Accept: application/json',\n 'Content-Length: '\n ),\n));\n\n$response = curl_exec($curl);\n\ncurl_close($curl);\necho $response;\n" - lang: PHP source: "setRequestUrl('{{baseUrl}}/invoices/upload/');\n$request->setRequestMethod('POST');\n$body = new http\\Message\\Body;\n$body->append('{\n \"xml\": \"\",\n \"name\": \"\"\n}');\n$request->setBody($body);\n$request->setOptions(array());\n$request->setHeaders(array(\n 'Content-Type' => 'application/json',\n 'Accept' => 'application/json',\n 'Content-Length' => ''\n));\n$client->enqueue($request)->send();\n$response = $client->getResponse();\necho $response->getBody();\n" - lang: PowerShell source: '$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" $headers.Add("Content-Type", "application/json") $headers.Add("Accept", "application/json") $headers.Add("Content-Length", "") $body = "{`n `"xml`": `"`",`n `"name`": `"`"`n}" $response = Invoke-RestMethod ''{{baseUrl}}/invoices/upload/'' -Method ''POST'' -Headers $headers -Body $body $response | ConvertTo-Json' - lang: Python source: "import requests\nimport json\n\nurl = \"{{baseUrl}}/invoices/upload/\"\n\npayload = json.dumps({\n \"xml\": \"\",\n \"name\": \"\"\n})\nheaders = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Content-Length': ''\n}\n\nresponse = requests.request(\"POST\", url, headers=headers, data=payload)\n\nprint(response.text)\n" - lang: Python source: "import http.client\nimport json\n\nconn = http.client.HTTPSConnection(\"{{baseUrl}}\")\npayload = json.dumps({\n \"xml\": \"\",\n \"name\": \"\"\n})\nheaders = {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Content-Length': ''\n}\nconn.request(\"POST\", \"/invoices/upload/\", payload, headers)\nres = conn.getresponse()\ndata = res.read()\nprint(data.decode(\"utf-8\"))" - lang: Ruby source: "require \"uri\"\nrequire \"json\"\nrequire \"net/http\"\n\nurl = URI(\"{{baseUrl}}/invoices/upload/\")\n\nhttp = Net::HTTP.new(url.host, url.port);\nrequest = Net::HTTP::Post.new(url)\nrequest[\"Content-Type\"] = \"application/json\"\nrequest[\"Accept\"] = \"application/json\"\nrequest[\"Content-Length\"] = \"\"\nrequest.body = JSON.dump({\n \"xml\": \"\",\n \"name\": \"\"\n})\n\nresponse = http.request(request)\nputs response.read_body\n" - lang: Shell source: "printf '{\n \"xml\": \"\",\n \"name\": \"\"\n}'| http --follow --timeout 3600 POST '{{baseUrl}}/invoices/upload/' \\\n Content-Type:'application/json' \\\n Accept:'application/json' \\\n Content-Length:" - lang: Shell source: "wget --no-check-certificate --quiet \\\n --method POST \\\n --timeout=0 \\\n --header 'Content-Type: application/json' \\\n --header 'Accept: application/json' \\\n --header 'Content-Length: ' \\\n --body-data '{\n \"xml\": \"\",\n \"name\": \"\"\n}' \\\n '{{baseUrl}}/invoices/upload/'" - lang: Swift source: "import Foundation\n#if canImport(FoundationNetworking)\nimport FoundationNetworking\n#endif\n\nvar semaphore = DispatchSemaphore (value: 0)\n\nlet parameters = \"{\\n \\\"xml\\\": \\\"\\\",\\n \\\"name\\\": \\\"\\\"\\n}\"\nlet postData = parameters.data(using: .utf8)\n\nvar request = URLRequest(url: URL(string: \"{{baseUrl}}/invoices/upload/\")!,timeoutInterval: Double.infinity)\nrequest.addValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\nrequest.addValue(\"application/json\", forHTTPHeaderField: \"Accept\")\nrequest.addValue(\"\", forHTTPHeaderField: \"Content-Length\")\n\nrequest.httpMethod = \"POST\"\nrequest.httpBody = postData\n\nlet task = URLSession.shared.dataTask(with: request) { data, response, error in \n guard let data = data else {\n print(String(describing: error))\n semaphore.signal()\n return\n }\n print(String(data: data, encoding: .utf8)!)\n semaphore.signal()\n}\n\ntask.resume()\nsemaphore.wait()\n" components: schemas: UploadXML: properties: name: description: Valor opcional, en caso de no existir, se coloca el UUID. title: Nombre del archivo type: string xml: description: El XML en base 64 title: XML type: string required: - xml title: UploadXML type: object UploadXMLResult: properties: message: description: Mensaje de éxito o de error que acompaña al status type: string result: description: Contiene la información del endpoint donde se puede consultar el status de la carga properties: url: description: URL de Firebase donde se puede consultar el status de la carga type: string type: object status: description: Indica el status de la llamada, 1.- Éxito, 0.- Error type: number type: object securitySchemes: APIKey: description: Llave de API relacionada al usuario que hace la petición. in: header name: Authorization type: apiKey x-tagGroups: - name: Conciliación tags: - Conciliación - name: Tesorería tags: - Movimientos bancarios - name: Documentos fiscales tags: - Listado de documentos fiscales - Cargar un documento fiscal - Status de documentos fiscales - name: Contabilidad tags: - Balanza de comprobación - Pólizas manuales - Saldo de una cuenta