You have to define a single type (Int or String) for your data structure and use init with Decoder to make a custom parsing.
struct MyData: Decodable {
    let value: Int // Could be Int or String from different services
}
extension MyData {
    enum CodingKeys: String, CodingKey {
        case value
    }
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        do {
            value = try container.decode(Int.self, forKey: .value)
        } catch {
            let stringValue = try container.decode(String.self, forKey: .value)
            if let valueInt = Int(stringValue) {
                value = valueInt
            } else {
                var codingPath = container.codingPath
                codingPath.append(CodingKeys.value)
                let debugDescription = "Could not create Int from String \(stringValue) of field \(CodingKeys.value.rawValue)"
                let context = DecodingError.Context(codingPath: codingPath, debugDescription: debugDescription)
                throw DecodingError.dataCorrupted(context)
            }
        }
    }
}